2016-02-24 3 views
3

Я хотел бы создать trimmedText недвижимость для UITextView и UITextField. Вот что я сделал:Быстрые протоколы: скрыть некоторые свойства

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? в UITextField и, как String! в UITextView (whyyyy ?!> _ <). Теперь я хотел бы скрыть это свойство, чтобы избежать загромождения 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'

Я из идей.

ответ

2

я был бы склонен идти с:

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 ?? "") 
    } 
} 

Итак, вы избежать дублирования тяжелую работу, делая это в общей и частной функции и расширения на UITextField и UITextView сделать минимум, который им нужно сделать.

0

Вы объявляете TrimmedTextSupporting в качестве внутреннего протокола. Если вы не хотите, чтобы объявить trimmedText, как internal объявить 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" 
+1

являются свойства 'протокола TrimmedTextSupporting' доступны за пределами файла, если он объявлен как частный? –

+0

@deville Нет, это должно быть в одном файле ... Я вижу вашу проблему сейчас. Позвольте мне пойти и продолжить работу над лучшим ответом. – JAL

-1

Или вы можете позволить trimmedText не требуется, установите опцию.

(если вы хотите использовать по желанию в Swift, вы должны позволить протокол быть @objc)

@objc protocol TrimmedTextSupporting: class { 
    optional var trimmedText: String { get } 
}