代码:
import UIKit
import Cartography
class TimelineViewController: UITableViewController {
//class TimelineViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
// var tableView:UITableView
var memoItemList:[MemoItem]
init(){
self.memoItemList = [MemoItem]()
super.init(nibName: nil, bundle: nil)
// self.tableView = UITableView()
//
// gLog.debug("self.tableView=\(self.tableView)")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
if let tabBarController = self.tabBarController {
TabBarHeight = tabBarController.tabBar.frame.height //49
}
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.backgroundColor = UIColor.whiteColor()
self.tableView.separatorStyle = .None
self.tableView.registerClass(TimelineTableViewCell.self, forCellReuseIdentifier: TimelineTableViewCellId)
// self.tableView.estimatedRowHeight = TimelineTableViewCellEstimatedRowHeight
self.view.addSubview(self.tableView)
constrain(tableView){ tableView in
//statusBarFrame=(0.0, 0.0, 320.0, 20.0)
tableView.top == tableView.superview!.top + UIApplication.sharedApplication().statusBarFrame.height
tableView.bottom == tableView.superview!.bottom – TabBarHeight
tableView.left == tableView.superview!.left
tableView.right == tableView.superview!.right
}
initDemoData()
}
self.view.addSubview(self.tableView)
出错:
2016-05-19 17:21:01.364 QorosSales[23745:605682] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Can’t add self as subview’
*** First throw call stack:
(
0 CoreFoundation 0x000000010e8a5f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000110895bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010e8a5e6d +[NSException raise:format:] + 205
3 UIKit 0x000000010f654982 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 123
4 UIKit 0x000000010f6ad4a2 -[UITableView _addSubview:positioned:relativeTo:] + 50
5 QorosSales 0x000000010d741e9c _TFC10QorosSales22TimelineViewController11viewDidLoadfT_T_ + 2156
6 QorosSales 0x000000010d742022 _TToFC10QorosSales22TimelineViewController11viewDidLoadfT_T_ + 34
7 UIKit 0x000000010f703a90 -[UIViewController loadViewIfRequired] + 738
8 UIKit 0x000000010f703c8e -[UIViewController view] + 27
9 UIKit 0x000000010f746e80 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 360
10 UIKit 0x000000010f743069 -[UITabBarController _setSelectedViewController:] + 311
11 UIKit 0x000000010f7464e9 -[UITabBarController _tabBarItemClicked:] + 245
12 UIKit 0x000000010f5df8be -[UIApplication sendAction:to:from:forEvent:] + 75
13 UIKit 0x000000010f8b3b76 -[UITabBar _sendAction:withEvent:] + 451
14 UIKit 0x000000010f5df8be -[UIApplication sendAction:to:from:forEvent:] + 75
15 UIKit 0x000000010f6e6410 -[UIControl _sendActionsForEvents:withEvent:] + 467
16 UIKit 0x000000010f8b7fd1 -[UITabBar(Static) _buttonUp:] + 103
17 UIKit 0x000000010f5df8be -[UIApplication sendAction:to:from:forEvent:] + 75
18 UIKit 0x000000010f6e6410 -[UIControl _sendActionsForEvents:withEvent:] + 467
19 UIKit 0x000000010f6e57df -[UIControl touchesEnded:withEvent:] + 522
20 UIKit 0x000000010f625308 -[UIWindow _sendTouchesForEvent:] + 735
21 UIKit 0x000000010f625c33 -[UIWindow sendEvent:] + 683
22 UIKit 0x000000010f5f29b1 -[UIApplication sendEvent:] + 246
23 UIKit 0x000000010f5ffa7d _UIApplicationHandleEventFromQueueEvent + 17370
24 UIKit 0x000000010f5db103 _UIApplicationHandleEventQueue + 1961
25 CoreFoundation 0x000000010e7db551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
26 CoreFoundation 0x000000010e7d141d __CFRunLoopDoSources0 + 269
27 CoreFoundation 0x000000010e7d0a54 __CFRunLoopRun + 868
28 CoreFoundation 0x000000010e7d0486 CFRunLoopRunSpecific + 470
29 GraphicsServices 0x0000000113bf09f0 GSEventRunModal + 161
30 UIKit 0x000000010f5de420 UIApplicationMain + 1282
31 QorosSales 0x000000010d769462 main + 114
32 libdyld.dylib 0x0000000111eee145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
self.view.addSubview
之前的:
调试信息是:
(lldb) po self.tableView
<UITableView: 0x7f80dc01b800; frame = (0 20; 375 647); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7f80da4499f0>; layer = <CALayer: 0x7f80da400080>; contentOffset: {0, 0}; contentSize: {0, 0}>
(lldb) po self.tableView.subviews
▿ 1 elements
– [0] : <UITableViewWrapperView: 0x7f80da430010; frame = (0 0; 375 647); gestureRecognizers = <NSArray: 0x7f80da42e540>; layer = <CALayer: 0x7f80da430340>; contentOffset: {0, 0}; contentSize: {375, 647}>
(lldb) po self.tableView.subviews[0]
<UITableViewWrapperView: 0x7f80da430010; frame = (0 0; 375 647); gestureRecognizers = <NSArray: 0x7f80da42e540>; layer = <CALayer: 0x7f80da430340>; contentOffset: {0, 0}; contentSize: {375, 647}>
(lldb) po self.tableView.subviews[0].subviews
0 elements
(lldb) po self.tableView.superview
nil
搜:
UITableViewController tableview Can’t add self as subview
iphone – iOS app error – Can’t add self as subview – Stack Overflow
Can’t add self as subview – 苹果君的工作室 – 博客频道 – CSDN.NET
‘Can’t add self as subview’崩溃日志详解 – 颜妍 – 博客园
ios应用错误- 不能添加自身作为subview _iOS app error – Can’t add self as subview_ios_帮酷问答
UITableView Crashed · Issue #1 · alexyan/ios-learning
然后再去看看现在的frame,是已经有值了:
(lldb) po self.tableView.frame
▿ CGRect
▿ origin : CGPoint
– x : 0.0
– y : 20.0
▿ size : CGSize
– width : 375.0
– height : 647.0
(lldb) po UIScreen.mainScreen().bounds
▿ CGRect
▿ origin : CGPoint
– x : 0.0
– y : 0.0
▿ size : CGSize
– width : 375.0
– height : 667.0 { … }
所以:
直接去设置对应的frame,好像就可以了?
(lldb) po self.parentViewController
▿ Optional<UIViewController>
▿ Some : <QorosSales.MainTabViewController: 0x7f80da61df40>
(lldb) po self.parentViewController?.view
▿ Optional<UIView>
– Some : <UILayoutContainerView: 0x7f80da4107c0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7f80da410250>>
(lldb) po self
<QorosSales.TimelineViewController: 0x7f80da44cd40>
(lldb) po self.tableView
<UITableView: 0x7f80dc01b800; frame = (0 20; 375 647); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7f80da4499f0>; layer = <CALayer: 0x7f80da400080>; contentOffset: {0, 0}; contentSize: {0, 0}>
(lldb) po self.view
<UITableView: 0x7f80dc01b800; frame = (0 20; 375 647); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7f80da4499f0>; layer = <CALayer: 0x7f80da400080>; contentOffset: {0, 0}; contentSize: {0, 0}>
结果去修正了顶部和底部的高度:
override func viewDidLoad() {
super.viewDidLoad()
if let tabBarController = self.tabBarController {
TabBarHeight = tabBarController.tabBar.frame.height //49
gLog.debug("TabBarHeight=\(TabBarHeight)")
}
// self.tableView.delegate = self
// self.tableView.dataSource = self
//self.tableView.backgroundColor = UIColor.whiteColor()
self.tableView.backgroundColor = UIColor.greenColor()
self.tableView.separatorStyle = .None
self.tableView.registerClass(TimelineTableViewCell.self, forCellReuseIdentifier: TimelineTableViewCellId)
// self.tableView.estimatedRowHeight = TimelineTableViewCellEstimatedRowHeight
// self.view.addSubview(self.tableView)
// constrain(tableView){ tableView in
// //statusBarFrame=(0.0, 0.0, 320.0, 20.0)
// tableView.top == tableView.superview!.top + UIApplication.sharedApplication().statusBarFrame.height
// tableView.bottom == tableView.superview!.bottom – TabBarHeight
// tableView.left == tableView.superview!.left
// tableView.right == tableView.superview!.right
// }
gLog.debug("self.view.frame=\(self.view.frame)") //self.view.frame=(0.0, 20.0, 375.0, 647.0)
self.view.frame = UIEdgeInsetsInsetRect(self.view.frame, UIEdgeInsetsMake(UIApplication.sharedApplication().statusBarFrame.height, 0, TabBarHeight, 0))
gLog.debug("self.view.frame=\(self.view.frame)")
//self.view.frame=(0.0, 20.0, 375.0, 598.0)
//(0.0, 40.0, 375.0, 578.0)
initDemoData()
}
但是view还是顶部置顶显示了:
觉得很是奇怪:
顶部都设置了40了。
搜:
UITableViewController tableview frame
iphone – How to resize UITableView in UITableViewController with section header – Stack Overflow
如何更改uitableviewcontroller默认tableview的frame啊 | iOS开发 – CocoaChina CocoaChina_让移动开发更简单
结果去:
constrain(self.view, self.parentViewController!.view){ selfView, parentView in
//statusBarFrame=(0.0, 0.0, 320.0, 20.0)
selfView.top == parentView.top + UIApplication.sharedApplication().statusBarFrame.height
selfView.bottom == parentView.bottom – TabBarHeight
selfView.left == parentView.left
selfView.right == parentView.right
}
也还是出错:
fatalError("No common superview found between \(from.view) and \(to.view)")
iphone – Is an UITableView resizable? Can I assign a different frame? – Stack Overflow
[总结]
此处的iOS自带的UITableViewController,自带的tableView:
@available(iOS 2.0, *)
public class UITableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
public init(style: UITableViewStyle)
public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
public init?(coder aDecoder: NSCoder)
public var tableView: UITableView!
@available(iOS 3.2, *)
public var clearsSelectionOnViewWillAppear: Bool // defaults to YES. If YES, any selection is cleared in viewWillAppear:
@available(iOS 6.0, *)
public var refreshControl: UIRefreshControl?
}
内部是:
self.view == self.tableView
所以此处如果执行:
self.view.addSubview(self.tableView)
等价于自己添加自己,所以报错:
Can’t add self as subview
解决办法是:
UITableViewController中不能执行:
self.view.addSubview(self.tableView)
-》但是此处就没法去添加对应的约束去控制tableView的高度了。。。
-》而默认的UITableViewController的tableview的顶部,就和状态栏重叠了。。
-》所以:说是,对于UITableViewController
是没有比较好办法去调整tableView的frame的
-》只能自己去实现UIViewController,加上UITableViewDataSource and UITableViewDelegate
-》这和之前自己的用法一样,即没法用UITableViewController了啊。。
-》iOS系统自己实现的UITableViewController,连tableView的frame都不能设置,也太烂了吧。。。
-》算了,懒得理了,还是自己用UIViewController,加上UITableViewDataSource and UITableViewDelegate吧。
转载请注明:在路上 » [已解决]UITableViewController中对于tableView去addSubview出错:exception NSInvalidArgumentException reason Can’t add self as subview