Group Group Group Group Group Group Group Group Group

raywenderlich.com Forums

Core Text Tutorial for iOS: Making a Magazine App

Learn how to make your own magazine app with custom text layout in this Core Text tutorial for iOS.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3051-core-text-tutorial-for-ios-making-a-magazine-app

Can this be updated to do Swift and the current xcode?

Hi,

Here i have changed to swift 3, There is something need to change

Overlapping text with image
Add video url as hyper link,
Touch to open video url
Video link not showing up
provide custom UIView implementation.

thank you for this up date of project but, I’m sorry. I’m trying to translate also the parser in swift 3.

now I’ve translated but I don’t know why It doesn’t applicate the changes.

this is the code of the parser

can you help me?

import UIKit
import CoreText

class MarkupParser: NSObject {
    var font = ""
    var color = UIColor()
    var strokeColor = UIColor()
    var strokeWidth:Float = 0.0
    
    var images = [UIImage]()
    
    override init() {
        font = "Helvetica"
        color = UIColor.black
        strokeColor = UIColor.white
        strokeWidth = 0.0
    }
    
    func attrStringFromMarkup(markup:NSString) -> NSAttributedString {
        let aString = NSMutableAttributedString(string: "")
        do {
            let regex = try NSRegularExpression(pattern: "(.*?)(<[^>]+>|\\Z)", options: [NSRegularExpression.Options.caseInsensitive,NSRegularExpression.Options.dotMatchesLineSeparators])
            let chunks = regex.matches(in: markup as String, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, markup.length))
            
            for var b in chunks {
                let parts = markup.substring(with: b.range).components(separatedBy: "<")
                let fontRef = CTFontCreateWithName(self.font as CFString?, 24.0, nil)
                let attrs:[String:AnyObject] = [kCTForegroundColorAttributeName as String : self.color.cgColor, kCTFontAttributeName as String:fontRef, kCTStrokeColorAttributeName as String:self.strokeColor.cgColor, kCTStrokeWidthAttributeName as String:NSNumber.init(value: self.strokeWidth)]
                aString.append(NSAttributedString(string: parts[0], attributes: attrs))
                
                if parts.count > 1 {
                    let tag = parts[1] as NSString
                    if tag.hasPrefix("font") {
                        //stroke color
                        let sColorRegex = try NSRegularExpression(pattern: "(?<=strokeColor=\")\\w+", options: NSRegularExpression.Options(rawValue: 0))
                        sColorRegex.enumerateMatches(in: tag as String, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, tag.length), using: { (match, flags, stop) in
                            if tag.substring(with: (match?.range)!) == "none" {
                                self.strokeWidth = 0.0
                            }else{
                                self.strokeWidth = -3.0
                                let colorSel = NSSelectorFromString("red")
                                self.strokeColor = UIColor.perform(colorSel).takeUnretainedValue() as! UIColor
                            }
                        })
                        
                        //color
                        let colorRegex = try NSRegularExpression(pattern: "(?<=color=\")\\w+", options: NSRegularExpression.Options(rawValue: 0))
                        colorRegex.enumerateMatches(in: tag as String, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, tag.length), using: { (match, flags, stop) in
                            let colorSel = NSSelectorFromString("blue")
                            //self.color = UIColor.perform(colorSel).takeUnretainedValue() as! UIColor
                            self.color = UIColor.blue
                        })
                        
                        //face
                        let faceRegex = try NSRegularExpression(pattern: "(?<=face=\")[^\"]+", options: NSRegularExpression.Options(rawValue: 0))
                        faceRegex.enumerateMatches(in: tag as String, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSMakeRange(0, tag.length), using: { (match, flags, stop) in
                            self.font = tag.substring(with: (match?.range)!)
                        })
                    }
                }
            }
            
        } catch  {
            print("errore")
        }
        return aString
    }
}

UPDATE:

I’ve fount an other problem:il CTView write only the string but not insert the attributes

I’ve follow the tutorial and I translated the code in swift 3. anyone know the solution?

super.draw(rect)
        let context = UIGraphicsGetCurrentContext()
        // Flip the coordinate system
        
        context!.textMatrix = CGAffineTransform.identity
        context!.translateBy(x: 0, y: self.bounds.size.height+40)
        context!.scaleBy(x: 1.0, y: -1.0)

        let path = CGMutablePath()
        path.addRect(self.bounds)
        
        //let attString = NSAttributedString(string: "Hello Core Text World!")
        let p = MarkupParser.init()
        let attString:NSAttributedString = p.attrStringFromMarkup(markup: "Hello <font color=\"red\">core text <font color=\"blue\">world!")
        
        let stringa = NSMutableAttributedString(string: "Hello")
        stringa.append(NSMutableAttributedString(string: "Core Text", attributes: [kCTForegroundColorAttributeName as String:UIColor.red]))
        
        
        //MarkupParser* p = [[[MarkupParser alloc] init] autorelease];
        //NSAttributedString* attString = [p attrStringFromMarkup: @"Hello <font color=\"red\">core text <font color=\"blue\">world!"];
        
        
        
        let frameSetter = CTFramesetterCreateWithAttributedString(CFAttributedStringCreate(nil, stringa.string as CFString!, nil))
        let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, stringa.length), path, nil)
        CTFrameDraw(frame, context!)