[英]Swift protocol properties with delegates
我正在嘗試通過協議和擴展在 controller 上設置成功/錯誤視圖。
我想要實現的是,我想進入 state,它足以在 controller 上實現協議,並從那里訪問 successView(沒有額外的樣板)。
這是我到目前為止所擁有的:
protocol SucessViewProtocol where Self: UIViewController {
func initSuccessView()
var successView: UIView! { get set }
var topConstraint: NSLayoutConstraint! { set get }
func showSuccess()
func hideSucess()
}
extension SucessViewProtocol {
func showSuccess() {
//animate displaying success message
}
func hideSucess() {
//animate hiding success message
}
func initSuccessView() {
successView = UIView()
topConstraint = NSLayoutConstraint()
// init success view and top constraint
}
}
現在,當我在 controller 上實現協議時,它看起來像這樣:
// MARK: SuccessView
extension ConsumingViewController: SucessViewProtocol {
var successView: UIView! {
get {
//getter
}
set {
//setter
}
}
var topConstraint: NSLayoutConstraint! {
get {
//getter
}
set {
//setter
}
}
}
我想我的問題很明顯,因為我在實現 SucessViewProtocol 的 controller 中獲得了 successView 和 topConstraint 作為屬性。 我正在從擴展中的協議初始化屬性,所以我需要的只是訪問這些屬性(而不是在我的控制器中再次聲明它們)。 我想我在協議 - 擴展 - controller 之間遺漏了一些“膠水”部分
我希望能夠在 controller 上實現該協議,調用initSuccessView()
並從那里調用showSuccess
和hideSuccess
就足夠了。
編輯:
這就是我想使用這個結構的方式:
class ConsumingViewController: UIViewController {
func viewDidLoad() {
initSuccessView()
loadData()
}
private func loadData() {
//successfullyloaded
showSuccess()
}
}
// MARK: SuccessView
extension ConsumingViewController: SucessViewProtocol {
var successView: UIView! {
get {
//getter
}
set {
//setter
}
} *PROBLEMATIC*
var topConstraint: NSLayoutConstraint! {
get {
//getter
}
set {
//setter
}
} *PROBLEMATIC*
}
正如我所說,問題在於屬性 successView 和 topConstraing 在 ConsumingViewController 中被重新聲明(因為它們是協議的一部分)。 我需要在 controller 中實際上不可見,而只是在擴展中使用。 但是擴展中的存儲屬性存在問題......
可能是你想要的嗎?
protocol SucessViewProtocol {
func showSuccess()
func hideSucess()
}
fileprivate struct Key {
static var runtimeKey: Int = 0
}
extension SucessViewProtocol where Self: UIViewController {
var successView: UIView? {
get {
return objc_getAssociatedObject(self, &Key.runtimeKey) as? UIView
}
set {
objc_setAssociatedObject(self, &Key.runtimeKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
func showSuccess() {
successView = UIView()
//animate displaying success message
view.addSubview(successView)
}
func hideSucess() {
//animate hiding success message
successView?.removeFromSuperview()
}
}
像這樣在主 scope 中添加協議變量而不是擴展 scope UIViewController。
public class ViewController: UIViewController, SucessViewProtocol {
var successView: UIView!
var topConstraint: NSLayoutConstraint!
}
通過這樣做,您不需要為屬性定義 getter 和 setter
在 ViewDidLoaded 中,您可以初始化SuccessView:
public override func viewDidLoad() {
super.viewDidLoad()
self.initSuccessView()
}
並調用自定義 function:
func show() {
self.showSuccess()
}
func hide() {
self.hideSucess()
}
您只需要向擴展添加屬性,並使它們成為可選的。
protocol SucessViewProtocol where Self: UIViewController {
func initSuccessView()
var successView: UIView! { get set }
var topConstraint: NSLayoutConstraint! { set get }
func showSuccess()
func hideSucess()
}
extension SucessViewProtocol {
// 👇🏼------ these 2 properties added ------👇🏼
var successView: UIView! { get{ nil } set{} }
var topConstraint: NSLayoutConstraint! { get{ nil } set{} }
func showSuccess() {}
func hideSucess() {}
func initSuccessView() {
successView = UIView()
topConstraint = NSLayoutConstraint()
}
}
然后,當您在ConsumingViewController
上遵循SucessViewProtocol
時,您將不需要實現屬性。
// MARK: SuccessView
extension ConsumingViewController: SucessViewProtocol {
// There's NO compiler error here!
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.