2015年6月24日 星期三

更新ASTextNode文字

//重新給文字
self.textNode.attributedString = mutableAttributedString.copy() as! NSAttributedString
//取消上次的計算,然後重算大小
self.textNode.invalidateCalculatedSize()
self.textNode.measure(CGSizeMake(DefaultConfig.SCREEN_WIDTH, CGFloat(FLT_MAX)))

self.textNode.setNeedsLayout()

2015年6月23日 星期二

swift Range <---> objc NSRange 互換

extension String {
    func rangeFromNSRange(nsRange : NSRange) -> Range<String.Index>? {
        if let from = String.Index(self.utf16.startIndex + nsRange.location, within: self),
            let to = String.Index(self.utf16.startIndex + nsRange.location + nsRange.length, within: self) {
                return from ..< to
        }
        return nil
    }

    func NSRangeFromRange(range : Range<String.Index>) -> NSRange {
        let utf16view = self.utf16
        let from = String.UTF16View.Index(range.startIndex, within: utf16view)
        let to = String.UTF16View.Index(range.endIndex, within: utf16view)
        return NSMakeRange(from - utf16view.startIndex, to - from)
    }
}

2015年6月22日 星期一

利用closure的特性來解決callback時間差的問題

如果你要更新你的cell,但你的cell是reuse的,那第一時間用url去抓的image,可能在你滑動的過程中,callback回來時cell已經改放其他的data了。
原本我是想在download image的callback中加入一個key(在下例中是userName)來比對是否跟目前cell的userName相同,但這麼一來,就會破壞了download image API的內聚性。

在swift中比較好的做法是利用closure的特性來解決callback時間差的問題,
closure會把參數copy一份出來,而用self.去接的則是將外部的參數call by reference,
於是我們比較userName == self?.userName 就會等於是比較目前的跟之前的變數差異。
這樣就解決了。

    func setData(displayName: String, userName: String) {
        self.userName = userName
        
        WebImageFetcher.sharedInstance.getImageWithDisplayId(userName, size: ImageSizeEnum.SIZE_96X) {
            [weak self] (data) in
            if let img = data {
                if userName == self?.userName {
                    self?.iconView.image = data
                }
            }
        }
    }

2015年6月17日 星期三

客製化調整xib constraint的正確方式

//在其他func中呼叫setNeedsUpdateConstraints(在這以layoutSubviews為例)
override func layoutSubviews() {
        setNeedsUpdateConstraints()
    }

//把你要做的調整放在updateConstraints中
    override func updateConstraints() {
        textViewWidthConstraint.constant = scrollView.frame.width - imageViewWidthConstraint.constant
        super.updateConstraints()
    }

調整scrollView的內容位置到目前的textView的位置

 func fitScrollView(shouldMove: Bool) {
        if let scrollView = scrollView {
            var frame = inputTextField.frame
            var newSize = inputTextField.sizeThatFits(CGSizeMake(frame.width, CGFloat.max))
            frame.size.height = inputTextField.contentSize.height
            textViewHeightConstraint.constant = newSize.height
            textViewWidthConstraint.constant = scrollView.frame.width - imageViewWidthConstraint.constant
           
            let cursorPosition = inputTextField.caretRectForPosition(inputTextField.selectedTextRange?.start).origin
            if cursorPosition.y.isInfinite {
                var offset = inputTextField.frame.origin.y - scrollView.frame.size.height + newSize.height
                if offset > 0 {
                    if shouldMove {
                        scrollView.setContentOffset(CGPointMake(0, offset), animated: true)
                    } else {
                        scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
                    }
                }
            }
        }
    }

2015年6月10日 星期三

抓到目前遊標(cursor)的位置

let cursorPosition = self.inputTextField.caretRectForPosition(self.inputTextField.selectedTextRange?.start).origin
        println("x:\(cursorPosition.x) y:\(cursorPosition.y)")