2016-04-11 103 views
0

我在一个iOS应用程序中实现了一个用户窗体,该窗体同时使用了一个UIPickerViewUIDatePicker作为用户的输入设备。我已经将它们中的每一个都实现为场景中主要UIViewController的外部视图,并通过添加和删除约束来显示和隐藏使用autolayout用UIButton实现UIDatePicker和UIPickerView

这是我的问题:我维护单独的约束和隐藏/显示方法为这些视图中的每一个动画进和出。这是很多重复的代码,我感觉必须有一个更干净的方式来做到这一点,因为它似乎是iOS应用程序中非常常见的设计模式。我对此很新,所以我觉得我错过了一些东西。

是否有比这更好的设计模式使用多个输入设备到UIButtons?

下面是我使用的保持这种代码的采样...

var datePickerViewBottomConstraint: NSLayoutConstraint! 
var datePickerViewTopConstraint: NSLayoutConstraint! 
var storagePickerViewBottomConstraint: NSLayoutConstraint! 
var storagePickerViewTopConstraint: NSLayoutConstraint! 

@IBAction func storageButtonClicked(sender: UITextField) { 

    storagePickerView.translatesAutoresizingMaskIntoConstraints = false 
    storagePickerViewBottomConstraint = storagePickerView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor) 

    UIView.animateWithDuration(0.4, animations: { 
     self.storagePickerViewTopConstraint.active = false 
     self.storagePickerViewBottomConstraint.active = true 
    self.view.layoutIfNeeded() 
    }) 
} 

@IBAction func datePumpedClicked(sender: UIButton) { 

    datePickerView.translatesAutoresizingMaskIntoConstraints = false 
    datePickerViewBottomConstraint = datePickerView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor) 

    UIView.animateWithDuration(0.4, animations: { 
     self.datePickerViewTopConstraint.active = false 
     self.datePickerViewBottomConstraint.active = true 
     self.view.layoutIfNeeded() 
    }) 
} 

@IBAction func datePickerDismiss(sender: AnyObject) { 
    datePumpedLabel.setTitle(Global.dateFormatter.stringFromDate(datePicker.date), forState: UIControlState.Normal) 

    datePickerView.translatesAutoresizingMaskIntoConstraints = false 
    datePickerViewTopConstraint = datePickerView.topAnchor.constraintEqualToAnchor(view.bottomAnchor) 

    UIView.animateWithDuration(0.4, animations: { 
     self.datePickerViewBottomConstraint.active = false 
     self.datePickerViewTopConstraint.active = true 
     self.view.layoutIfNeeded() 
    }) 
} 

@IBAction func storagePickerDismiss(sender: AnyObject) { 

    storagePickerView.translatesAutoresizingMaskIntoConstraints = false 
    storagePickerViewTopConstraint = storagePickerView.topAnchor.constraintEqualToAnchor(view.bottomAnchor) 

    UIView.animateWithDuration(0.4, animations: { 
     self.storagePickerViewBottomConstraint.active = false 
     self.storagePickerViewTopConstraint.active = true 
     self.view.layoutIfNeeded() 
    })  
} 

这里是我的故事板的截图... Storyboard

回答

0

你们,我想出了一个更好的办法!

我最初缺少的东西是,当你从超级视图中移除视图时,所有的约束都被删除。这使事情变得更容易。

我为当前正在显示的视图保留了1个约束类变量,因此该视图可以动画变得不合适。

我还添加了一个“设置”功能,以获得viewdidload()上的视图。没有这个视图总是会在第一次出现时从顶部开始生成动画(无法找到解决方法)。

下面是我用什么:

var secondaryMenuBottomConstraint: NSLayoutConstraint! 

func setupSecondaryMenu(secondaryMenu: UIView){ 

    secondaryMenu.translatesAutoresizingMaskIntoConstraints = false 

    let topConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor) 
    let leftConstraint = secondaryMenu.leftAnchor.constraintEqualToAnchor(view.leftAnchor) 
    let rightConstraint = secondaryMenu.rightAnchor.constraintEqualToAnchor(view.rightAnchor) 

    view.addSubview(secondaryMenu) 
    NSLayoutConstraint.activateConstraints([topConstraint, leftConstraint, rightConstraint]) 
    self.view.layoutIfNeeded() 
    secondaryMenu.removeFromSuperview() 

} 

func showSecondaryMenu(secondaryMenu: UIView){ 
    //Close any open keyboards 
    amountTextField.resignFirstResponder() 
    notesTextField.resignFirstResponder() 

    //Add the view and then add constraints to show the submenu below the current view 
    secondaryMenu.translatesAutoresizingMaskIntoConstraints = false 
    let topConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor) 
    let leftConstraint = secondaryMenu.leftAnchor.constraintEqualToAnchor(view.leftAnchor) 
    let rightConstraint = secondaryMenu.rightAnchor.constraintEqualToAnchor(view.rightAnchor) 

    view.addSubview(secondaryMenu) 
    NSLayoutConstraint.activateConstraints([topConstraint, leftConstraint, rightConstraint]) 

    secondaryMenuBottomConstraint = secondaryMenu.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor) 

    //animate the view up into place 
    UIView.animateWithDuration(0.4, animations: { 
     topConstraint.active = false 
     self.secondaryMenuBottomConstraint.active = true 
     self.view.layoutIfNeeded() 
    }) 
} 

func dismissSecondaryMenu(secondaryMenu: UIView){ 
    if secondaryMenu.superview != nil { 
     secondaryMenu.translatesAutoresizingMaskIntoConstraints = false 
     let secondaryMenuTopConstraint = secondaryMenu.topAnchor.constraintEqualToAnchor(view.bottomAnchor) 
     self.secondaryMenuBottomConstraint.active = false 

     UIView.animateWithDuration(0.4, animations: { 
      secondaryMenuTopConstraint.active = true 

      self.view.layoutIfNeeded() 
     }, completion: {(finished:Bool) in 
       secondaryMenu.removeFromSuperview() 
     }) 
    } 
}