5

我想为和创建一个trimmedText属性。这是我所做的:UITextViewUITextField

protocol TrimmedTextSupporting: class {
  var _text: String? { get }
  var trimmedText: String { get }
}

extension TrimmedTextSupporting {
  var trimmedText: String {
    let text = self._text ?? ""
    return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
  }
}

extension UITextField: TrimmedTextSupporting {

  var _text: String? {
    return self.text
  }
}

extension UITextView: TrimmedTextSupporting {

  var _text: String? {
    return self.text
  }
}

我需要_text财产,因为text它被声明为String?inUITextFieldString!( UITextViewwhyyyy?! >_<)。现在我想隐藏这个属性以避免混乱 API。

这是我尝试过的:

1) 将其标记为private。编译器不允许这样做:'private' modifier cannot be used in protocols

2)将其分离为私有协议:

private protocol TextExposing {
  var _text: String? { get }
}

extension UITextField: TextExposing {
  var _text: String? {
    return self.text
  }
}

extension UITextView: TextExposing {
  var _text: String? {
    return self.text
  }
}

///////

protocol TrimmedTextSupporting: class {
  var trimmedText: String { get }
}

extension UITextField: TrimmedTextSupporting {}

extension UITextView: TrimmedTextSupporting {}

extension TrimmedTextSupporting where Self: TextExposing {

  // compiler error
  var trimmedText: String {
    let text = self._text ?? ""
    return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
  }
}

但是编译器再次抱怨: Property 'trimmedText' must be declared internal because it matches a requirement in internal protocol 'TrimmedTextSupporting'

我没主意了。

4

3 回答 3

4

我倾向于选择:

protocol TrimmedTextSupporting: class {
    var trimmedText: String { get }
}

extension TrimmedTextSupporting {

    private func trimText(text: String) -> String {
        return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    }
}

extension UITextField: TrimmedTextSupporting {

    var trimmedText: String {
        return trimText(text ?? "")
    }
}

extension UITextView: TrimmedTextSupporting {

    var trimmedText: String {
        return trimText(text ?? "")
    }
}

因此,您通过在共享和私有函数中完成这项工作,避免了重复繁重的工作,并且扩展UITextFieldUITextView完成了他们需要做的最少工作。

于 2016-02-24T14:31:32.567 回答
0

您声明TrimmedTextSupporting为内部协议。如果您不想声明trimmedTextinternal,请声明TrimmedTextSupporting为私有协议:

private protocol TrimmedTextSupporting: class {
    var trimmedText: String { get }
}

这编译得很好。

let textView = UITextView()
textView.text = "hello  "
print(textView.trimmedText) // "hello"

let textField = UITextField()
textField.text = "  world "
print(textField.trimmedText) // "world"
于 2016-02-24T14:26:15.143 回答
-1

或者你可以让 trimmedText 不是必需的,设置为可选。

(如果你想在 Swift 中使用 optional,你应该让协议为 @objc)

@objc protocol TrimmedTextSupporting: class {
     optional var trimmedText: String { get }
}
于 2016-02-24T14:42:03.680 回答