[已解决]Swift中键盘显示后调整TableView的显示高度后工具栏变黑色了
期间,需要去:
给一个container的View:chatView中的tableview和toolbar之间,添加约束限制
使得:
tableview1的高度=chatView的高度-toolbar的高度
(或者最好再加上
tableview的最底端==toolbar的最顶端)
注:
之前在别的代码中,就试过一次加约束,但是没成功:
感觉添加约束,好像有点复杂,难搞懂的样子。。
搜:
swift 添加约束
Swift自适应布局(Adaptive Layout)教程(一) – 程序员说
自动布局autolayout使用总结(源码含swift版本) – 厚积薄发 – 博客频道 – CSDN.NET
iOS学习之Autolayout(代码添加约束)-Swift & Objective-C IOS-苦咖啡
其中讲到了:
对于约束条件,加到哪个view上的逻辑
Swift语言Auto Layout入门教程:上篇 – CocoaChina 苹果开发中文站 – 最热的iPhone开发社区 最热的苹果开发社区 最热的iPad开发社区
Swift语言Auto Layout入门教程:下篇 – CocoaChina_让移动开发更简单
iOS 8 Auto Layout界面自动布局系列3-使用代码添加布局约束 – 51iOS.net
swift add constraints programmatically
ios – SWIFT | Adding constraints programmatically – Stack Overflow
ios – add constraints programmatically swift – Stack Overflow
提到了:
对于iOS 8之后,把约束条件加到哪个view上,已经不需要我们操心了:
可以用active即可:
学习AutoLayout(NSLayoutConstraint) – 简书
NSLayoutConstraint Class Reference
还是官网解释的清楚:
NSLayoutConstraint有个active属性
设置active为true或false,内部会调用addConstraint或removeConstraint,添加或删除约束条件到哪呢?到两个view的最接近的一个共有的父视图上
-》也就是:
iOS学习之Autolayout(代码添加约束)-Swift & Objective-C IOS-苦咖啡
http://www.cokco.cn/thread-10684-1-1.html
画的那些图:
“
- 兄弟 view 的 Constraint 添加到他们的 superview
两个 view 的父 view 是兄弟关系的,Constraint 添加到父 view 的 superview 上
如果两个 view 是 parent-child 关系,Constraint 添加到 parent view上
”
-》不过,此处对于active属性的话,貌似系统内部调用addConstraint或removeConstraint时会自动判断的,无需自己操心
-》上述的active,是对于单个的NSLayoutConstraint来说的
想要一次性地,激活或取消多个约束条件的话,才会去调用对应的:
activateConstraints或deactivateConstraints
等价于对于每个约束条件都去调用active=yes
-》需要注意的是:上述的active,activateConstraints或deactivateConstraints,都只是在iOS 8.0之后才有
用代码:
let heightConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.LessThanOrEqual, toItem: inputMessageToolbar, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0) //<NSLayoutConstraint:0x7f8952785960 UITableView:0x7f8953863800.bottom <= UIToolbar:0x7f89525b8300.top> heightConstraint.active = true |
没有效果:
好像是因为:
自己手动设置了frame了?
translatesAutoresizingMaskIntoConstraints
参考:
iOS: 让自定义控件适应Autolayout注意的问题 | Mgen
去设置
结果,点击出现输入框,应该出现键盘时,变成:
学习iOS 6.0的NSAutoLayout – [email protected]
学习AutoLayout(NSLayoutConstraint) – 简书
学习AutoLayout(UIScrollView) – 简书
然后用代码:
//add constraints for messageTableView self.messageTableView = UITableView() messageTableView.translatesAutoresizingMaskIntoConstraints = false let messageTopConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0) let messageBottomConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: (0 – toolbarHeight)) let messageLeftConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0) let messageRightConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0) NSLayoutConstraint.activateConstraints([ messageTopConstraint, messageBottomConstraint, messageLeftConstraint, messageRightConstraint]) chatView.addSubview(self.messageTableView) // let inputToolbarView = UIView(frame: CGRectMake( // 0, // 0, // //TODO: adjust according to iPhone screen width // self.view.frame.width – 60, //iPhone5:260, iPhone:315 // 30)) // print("inputToolbarView.frame=\(inputToolbarView.frame)") //for debug //inputToolbarView.backgroundColor = UIColor.greenColor() //add constraints let inputToolbarView = UIView() inputToolbarView.translatesAutoresizingMaskIntoConstraints = false let inputToolbarTopConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: (0 – toolbarHeight)) let inputToolbarBottomConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0) let inputToolbarLeftConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0) let inputToolbarRightConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0) NSLayoutConstraint.activateConstraints([ inputToolbarTopConstraint, inputToolbarBottomConstraint, inputToolbarLeftConstraint, inputToolbarRightConstraint]) chatView.addSubview(inputMessageToolbar) |
结果程序挂了:
2015-11-29 15:11:06.616 JianDao[50721:2654673] *** Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘Unable to activate constraint with items <UITableView: 0x7fc7d209b600; frame = (0 0; 0 0); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x7fc7d413ca10>; layer = <CALayer: 0x7fc7d1cf6760>; contentOffset: {0, 0}; contentSize: {0, 0}> and <UIView: 0x7fc7d413c2e0; frame = (0 0; 375 603); layer = <CALayer: 0x7fc7d413b910>> because they have no common ancestor. Does the constraint reference items in different view hierarchies? That’s illegal.’ *** First throw call stack: ( 0 CoreFoundation 0x000000010a002f45 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010929bdeb objc_exception_throw + 48 2 CoreFoundation 0x000000010a002e7d +[NSException raise:format:] + 205 3 Foundation 0x000000010901908e +[NSLayoutConstraint _addOrRemoveConstraints:activate:] + 383 4 JianDao 0x000000010897e23f _TFC7JianDao26MessageTableViewController11viewDidLoadfS0_FT_T_ + 5823 5 JianDao 0x00000001089804d2 _TToFC7JianDao26MessageTableViewController11viewDidLoadfS0_FT_T_ + 34 6 UIKit 0x000000010aca4cc4 -[UIViewController loadViewIfRequired] + 1198 7 UIKit 0x000000010acaac7b -[UIViewController __viewWillAppear:] + 120 8 UIKit 0x000000010acdaa37 -[UINavigationController _startCustomTransition:] + 1203 9 UIKit 0x000000010aceacdb -[UINavigationController _startDeferredTransitionIfNeeded:] + 712 10 UIKit 0x000000010acebcea -[UINavigationController __viewWillLayoutSubviews] + 57 11 UIKit 0x000000010ae91c85 -[UILayoutContainerView layoutSubviews] + 248 12 UIKit 0x000000010abc6e40 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 710 13 QuartzCore 0x000000010a89259a -[CALayer layoutSublayers] + 146 14 QuartzCore 0x000000010a886e70 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366 15 QuartzCore 0x000000010a886cee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 16 QuartzCore 0x000000010a87b475 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277 17 QuartzCore 0x000000010a8a8c0a _ZN2CA11Transaction6commitEv + 486 18 UIKit 0x000000010ab3d216 _afterCACommitHandler + 174 19 CoreFoundation 0x0000000109f2e947 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23 20 CoreFoundation 0x0000000109f2e8b7 __CFRunLoopDoObservers + 391 21 CoreFoundation 0x0000000109f2450b __CFRunLoopRun + 1147 22 CoreFoundation 0x0000000109f23e08 CFRunLoopRunSpecific + 488 23 GraphicsServices 0x000000010e6a3ad2 GSEventRunModal + 161 24 UIKit 0x000000010ab1230d UIApplicationMain + 171 25 JianDao 0x000000010890d2bd main + 109 26 libdyld.dylib 0x000000010c9ce92d start + 1 27 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException |
难道是顺序错了?
那么把那些约束条件,放到最后:
chatView.addSubview(self.messageTableView) chatView.addSubview(inputMessageToolbar) //add constraints for messageTableView messageTableView.translatesAutoresizingMaskIntoConstraints = false let messageTopConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: statusBarFrame.height + HeightNaviBar) let messageBottomConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: (0 – toolbarHeight)) let messageLeftConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0) let messageRightConstraint:NSLayoutConstraint = NSLayoutConstraint( item: messageTableView, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0) NSLayoutConstraint.activateConstraints([ messageTopConstraint, messageBottomConstraint, messageLeftConstraint, messageRightConstraint]) inputToolbarView.translatesAutoresizingMaskIntoConstraints = false let inputToolbarTopConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: (0 – toolbarHeight)) let inputToolbarBottomConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0) let inputToolbarLeftConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Left, multiplier: 1.0, constant: 0) let inputToolbarRightConstraint:NSLayoutConstraint = NSLayoutConstraint( item: inputToolbarView, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: chatView, attribute: NSLayoutAttribute.Right, multiplier: 1.0, constant: 0) NSLayoutConstraint.activateConstraints([ inputToolbarTopConstraint, inputToolbarBottomConstraint, inputToolbarLeftConstraint, inputToolbarRightConstraint]) |
虽然可以运行了,但是还是效果不对:
AutoLayout的三种设置方式之——NSLayoutConstraint代码篇 – 愤怒大熊猫 – 博客园
好像是:
父的view,此处的chatView,难道也是不能设置frame???
调试改为:
messageTableView.translatesAutoresizingMaskIntoConstraints = false // inputMessageToolbar.translatesAutoresizingMaskIntoConstraints = false // chatView.translatesAutoresizingMaskIntoConstraints = false |
出错:
2015-11-29 15:51:54.147 JianDao[51551:2697148] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don’t want. Try this: (1) look at each constraint and try to figure out which you don’t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you’re seeing NSAutoresizingMaskLayoutConstraints that you don’t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x7f9c8b0a9900 h=–& v=–& UIToolbar:0x7f9c88ee2700.midY ==>", "<NSAutoresizingMaskLayoutConstraint:0x7f9c8b0a9970 h=–& v=–& V:[UIToolbar:0x7f9c88ee2700(0)]>", "<NSAutoresizingMaskLayoutConstraint:0x7f9c88fe0c10 h=–& v=–& V:[UIView:0x7f9c88eee3c0(603)]>", "<NSLayoutConstraint:0x7f9c88efa3f0 UIToolbar:0x7f9c88ee2700.bottom == UIView:0x7f9c88eee3c0.bottom>" ) Will attempt to recover by breaking constraint Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. |
改为:
messageTableView.translatesAutoresizingMaskIntoConstraints = false inputMessageToolbar.translatesAutoresizingMaskIntoConstraints = false chatView.translatesAutoresizingMaskIntoConstraints = false |
没有警告了,但是效果还是不对:
参考:
代码添加constraint,设置translatesAutoresizingMaskIntoConstraints为NO的原因 – 1993奇葩 – 博客频道 – CSDN.NET
搜:
Layout is performed in three primary ways
找到:
Programmatically create a constraint – Swift | Ryan Wright
swift UIViewAutoresizing FlexibleTopMargin example
swift UIViewAutoresizing example
swift UIViewAutoresizing demo
最后的最后,还是没有搞定,如何通过添加约束条件的方式,实现在:
键盘显示的时候,调整chatView内的toolbar的位置以便得以显示出来toolbar
最后是通过autoresizingMask解决的:
详见:
[已解决]Swift中键盘显示后调整TableView的显示高度后工具栏变黑色了
抽空再去看看:
转载请注明:在路上 » [已解决]Swift中给UITableView和UIToolbar之间添加限制约束Constraint