亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

NSRange到范圍<String.Index>

NSRange到范圍<String.Index>

茅侃侃 2019-07-05 13:04:10
NSRange到范圍<String.Index>我如何轉換NSRange到Range<String.Index>在斯威夫特?我想使用以下方法UITextFieldDelegate方法:    func textField(textField: UITextField!,         shouldChangeCharactersInRange range: NSRange,         replacementString string: String!) -> Bool {textField.text.stringByReplacingCharactersInRange(???, withString: string)
查看完整描述

3 回答

?
四季花海

TA貢獻1811條經驗 獲得超5個贊

截至SWIFT 4(Xcode 9),SWIFT標準庫提供了在SWIFT字符串范圍之間進行轉換的方法(Range<String.Index>)和NSString范圍(NSRange)。例子:

let str = "a?b??c"let r1 = str.range(of: "??")!// String range to NSRange:let n1 = NSRange(r1, in: str)print((str as NSString).
substring(with: n1)) // ??// NSRange back to String range:let r2 = Range(n1, in: str)!print(str[r2]) // ??

因此,文本字段委托方法中的文本替換現在可以作為

func textField(_ textField: UITextField,
               shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool {

    if let oldString = textField.text {
        let newString = oldString.replacingCharacters(in: Range(range, in: oldString)!,
                                                      with: string)
        // ...    }
    // ...}

(SWIFT 3及更早版本的舊答案:)

斯威夫特1.2,String.Index有一個初始化器

init?(_ utf16Index: UTF16Index, within characters: String)

可以用來轉換NSRangeRange<String.Index>正確(包括所有表情符號、區域指示符或其他擴展的圖形素集群),而不中間轉換為NSString:

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

此方法返回任選字符串范圍,因為不是所有NSRangeS對給定的SWIFT字符串有效。

這個UITextFieldDelegate然后,可以將委托方法編寫為

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if let swRange = textField.text.rangeFromNSRange(range) {
        let newString = textField.text.stringByReplacingCharactersInRange(swRange, withString: string)
        // ...    }
    return true}

逆變換是

extension String {
    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)
    }}

一個簡單的測試:

let str = "a?b??c"let r1 = str.rangeOfString("??")!// String range to NSRange:let n1 = str.NSRangeFromRange(r1)println((str as NSString)
.substringWithRange(n1)) // ??// NSRange back to String range:let r2 = str.rangeFromNSRange(n1)!println(str.substringWithRange(r2)) // ??

SWIFT 2更新:

SWIFT 2版rangeFromNSRange()已經由Serhii Yakovenko在這個答案,我把它包括在這里是為了完整:

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

SWIFT 2版NSRangeFromRange()

extension String {
    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(utf16view.startIndex.distanceTo(from), from.distanceTo(to))
    }}

SWIFT 3更新(Xcode 8):

extension String {
    func nsRange(from range: Range<String.Index>) -> NSRange {
        let from = range.lowerBound.samePosition(in: utf16)
        let to = range.upperBound.samePosition(in: utf16)
        return NSRange(location: utf16.distance(from: utf16.startIndex, to: from),
                       length: utf16.distance(from: from, to: to))
    }}extension String {
    func range(from nsRange: NSRange) -> Range<String.Index>? {
        guard
            let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex),
            let to16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location + nsRange.length, limitedBy: utf16.endIndex),
            let from = from16.samePosition(in: self),
            let to = to16.samePosition(in: self)
            else { return nil }
        return from ..< to    }}

例子:

let str = "a?b??c"let r1 = str.range(of: "??")!// String range to NSRange:let n1 = str.nsRange(from: r1)print((str as NSString)
.substring(with: n1)) // ??// NSRange back to String range:let r2 = str.range(from: n1)!print(str.substring(with: r2)) // ??


查看完整回答
反對 回復 2019-07-05
  • 3 回答
  • 0 關注
  • 1155 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號