最新消息:20210917 已从crifan.com换到crifan.org

[已解决]UITableViewController中对于tableView去addSubview出错:exception NSInvalidArgumentException reason Can’t add self as subview

iOS crifan 3721浏览 0评论

代码:

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)")

ios – Change frame of UITableView of UITableViewController inside UINavigationController – Stack Overflow

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

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
100 queries in 0.289 seconds, using 23.37MB memory