Swift / 故事板解决方案
注意:下面的代码假设有一个自定义视图(在我的例子中是 ratingView),该视图将在 UITableView 上呈现。
我已经阅读了许多关于 SO 和类似问题的答案。这些来源的其他答案对我来说在不同程度上起作用(例如,视图已加载但未显示或无法访问,...)。我正在使用 Swift 2.0+,我正在分享使用UITableViewController执行此操作的完整解决方案。
创建一个到导航栏和视图的出口,你想把它带到 tableview 上。
//MARK:Outlets
@IBOutlet weak var navBar:UINavigationBar!
@IBOutlet var ratingView: MNGStarRating!
在我的例子中,我还想为 tableview 上的视图设置动画,所以我使用一个类变量来保存对拐点的引用和场景上方的一个点(屏幕外)。
var centerYInflection:NSLayoutConstraint!
var aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)
然后,viewDidLoad
我调用了一个函数(configureRatingViewAutoLayout),它为要在表格视图上设置动画的新视图配置和添加约束。
func configureRatingViewAutoLayout() {
//REQUIRED
self.navBar.superview?.addSubview(self.ratingView)
var newConstraints:[NSLayoutConstraint] = []
newConstraints.append(self.ratingView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor,constant: 10))
newConstraints.append(self.ratingView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor,constant: 10))
newConstraints.append(self.ratingView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor))
//hides the rating view above the scene
self.centerYInflection = self.ratingView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: self.aPointAboveScene)
//the priority must be set below 1000 if you intend to change it after it has been added to a view
self.centerYInflection.priority = 750
newConstraints.append(self.centerYInflection)
//constraints must be added to the container view of the two items
self.ratingView.superview?.addConstraints(newConstraints)
}
Nota Bene - 在 UITableViewController 上;self.view 是 self.tableView。他们指向相同的东西,所以我想也可以使用上面的 self.tableView 参考。
一段时间后...为了响应 UIControl 事件,我调用此方法。
@IBAction func toggleRatingView (sender:AnyObject?){
//REQUIRED
self.ratingView.superview?.layoutIfNeeded()
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.37, initialSpringVelocity: 0.99, options: [.CurveEaseOut], animations: { () -> Void in
if CGRectContainsRect(self.view.frame, self.ratingView.frame) {
//in frame ~ animate away
//I play a sound to alert the user something is happening
self.centerYInflection.constant = self.aPointAboveScene
self.centerYInflection.priority = UILayoutPriority(950)
//I disable portions of the UI
self.disableUIElements(nil)
} else {
//out of frame ~ animate in
//I play a different sound here
self.centerYInflection.constant = 0
self.centerYInflection.priority = UILayoutPriority(950)
//I enable the UI fully
self.enableUIElements(nil)
}
//REQUIRED
self.ratingView.superview?.setNeedsLayout()
self.ratingView.superview?.layoutIfNeeded()
}) { (success) -> Void in
//do something else
}
}
这些辅助方法可以配置为在视图呈现期间控制对场景中元素的访问。
func disableUIElements(sender:AnyObject?) {
//UI
}
func enableUIElements(sender:AnyObject?) {
//UI
}
注意事项
我的视图是 Storyboard 中的自定义视图(位于 tableview 之外但连接到 TableView 控制器)。该视图有一个
必需的用户运行时属性layer.zPosition
,其数值设置为 2(这确保它显示在 UITableView 的前面)。
如果您不想设置 zPosition,也可以尝试使用 bringSubviewToFront: 和 sendSubviewToBack: 方法(我认为 zPosition 更易于使用)

