2016-06-28 56 views
1

我试图让我的代码更有组织和可重用。我有一些功能和通知,允许滚动视图在键盘显示时向上移动,当键盘隐藏时向下滚动。它全部运作。但是,我将这些函数的映像用于我的项目的多个部分,这些部分在UIViewcontroller中具有scrollView。所以我想要创建更多的可重用代码,而不是在多个视图控制器中编写相同的代码。使代码在swift中更有条理

目前,在我的视图控制器之一,我有

var keyboard = CGRect() 

override func viewDidLoad() { 

    // Check notifications of keyboard activity 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PostVC.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PostVC.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil) 

    // Tap to hide keyboard 
    let hideTap = UITapGestureRecognizer(target: self, action: #selector(PostVC.hideKeyboard)) 
    hideTap.numberOfTapsRequired = 1 
    self.view.userInteractionEnabled = true 
    self.view.addGestureRecognizer(hideTap) 
} 

func hideKeyboard() { 
     self.view.endEditing(true) 
    } 


func keyboardWillShow(notification: NSNotification) { 

    keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey]!.CGRectValue())! 

    UIView.animateWithDuration(0.4) { 
     self.scrollView.contentSize.height = self.view.frame.size.height + self.keyboard.height/2 + UITabBarController().tabBar.frame.size.height 
    } 
} 

func keyboardWillHide(notification: NSNotification) { 

    UIView.animateWithDuration(0.4) { 
     self.scrollView.contentSize.height = 0 
    } 
} 

我升技新努力使代码更可重用。我不确定是否需要创建一个新类,或者只是创建UIViewcontroller的扩展并将其放在那里。我曾尝试创建的UIViewController的扩展,这样做

func keyboardWillShow(notification: NSNotification, _scrollView: UIScrollView) { } 

,并通过滚动视图的一个实例(@IBOutlet弱VAR滚动视图:UIScrollView中)到函数。但是,我在遇到#selector(keyboardWillShow(_:, keyboard: keyboard, scrollView: scrollView)时遇到了麻烦。它给我一个错误,说在表达式列表中的期望表达式(我认为它是在抱怨_ :)。我可能会完全错误的做法。任何人都可以请帮忙。

感谢,

+1

如果代码可能会在应用程序的许多地方重复使用,最好为共享代码的所有视图控制器创建一个基类。 –

+0

您是否研究过像'UIScrollView'这样的东西来创建[类扩展](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html)? – ZGski

回答

2

我会建议建立一个协议,将默认的实现作为协议的扩展。在协议中,你可以添加实现它的类应该有一个scrollView和一个键盘。请记住,协议扩展比基类更灵活,这就是为什么在Swift中经常使用的原因。

这里想到的一个例子

protocol Scrollable : class { 

    var scrollView: UIScrollView { get } 
    var keyboardRect: CGRect { get set } 
} 

extension Scrollable where Self : UIViewController { 

    func registerForKeyboardNotifications() { 

     NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillShowNotification, object: nil, queue: nil, usingBlock: { (notification) in 

      self.keyboardWillShow(notification) 
     }) 
     NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardWillHideNotification, object: nil, queue: nil, usingBlock: { (notification) in 

      self.keyboardWillHide(notification) 
     }) 
    } 

    func deregisterForKeyboardNotification() { 

     NSNotificationCenter.defaultCenter().removeObserver(self) 
    } 

    func keyboardWillShow(notification: NSNotification) { 

     self.keyboardRect = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey]!.CGRectValue())! 

     UIView.animateWithDuration(0.4) { 
      self.scrollView.contentSize.height = self.view.frame.size.height + self.keyboardRect.height/2 + UITabBarController().tabBar.frame.size.height 
     } 
    } 

    func keyboardWillHide(notification: NSNotification) { 

     UIView.animateWithDuration(0.4) { 
      self.scrollView.contentSize.height = 0 
     } 
    } 
} 

有,我用addObserverForName代替的addObserver因为以后不能用协议扩展容易使用。更多关于你可以在这里阅读 - Swift make protocol extension a Notification observer