I'm new to IOS programming so I apologize if my question is obvious.
I created a UIViewController in storyboard, which contains a UIScrollView and multiple subviews.
These subviews (most often UITextViews) are filled with content from an external API, and content can thus be nil : in this case I would need to remove that subview which is empty.
For now I set this view as an IBOutlet and in viewDidLoad, if content is nil, I call
[self.thatView removeFromSuperView];
Is there a more efficient way to do that, for instance in loadView, in order to prevent that view to even load?
Is the usual method to handle subviews layoutSubviews?
Thx for your help
Any call before viewDidLoad will cause you problems unfortunately, you need to finish the load of a view before you dismiss it.
Related
At what point in the UIViewController lifecycle is the subview property of self.view guaranteed to be populated with all the correct views? Note: I don't care about if they're laid out or not, just that they exist in the subview array. WWDC videos say that loadView, viewDidLoad, and init all don't come with that guarantee but viewWillLayoutSubviews is also late in the game.
The task I'm trying to perform in this instance is localization. In a common view controller class, I want to loop through all the subviews, see if they have a custom attribute set that identifies what localized string key is attached to that view, and then recurse through all that views subviews until the bottom of the view hierarchy is reached. Layout isn't important in this instance, just that the subviews are populated in the view controller.
At what point in the UIViewController lifecycle is the subview property of self.view guaranteed to be populated with all the correct views
The earliest point implemented by most apps is viewDidLoad. At that point you are guaranteed that self.view exists along with all the subviews from the storyboard, and that any outlets hooked up to this view controller from the storyboard have been populated.
I don't care about if they're laid out or not, just that they exist in the subview array
Exactly so. self.view and its nib-loaded subviews exist at this point, but their layout has not yet taken place and their frame is not necessarily correct. You don't care, so viewDidLoad is fine for your purposes.
I'm creating a ViewController that will contain as a portion of it a scrollView. In that scrollView I would like to include the view of another ViewController. When I set up this ViewController inside of the ScrollView, all of that ViewController's data is pulled from the web and even it's "ViewDidLoad" method is called. However, nothing appears except for the tableViewLines and a spinner I've created to show the page is loading. Here is what it looks like (the ScrollView in question is under Commitments and Awards):
What should be loaded inside the scrollView is a tableView that looks like this:
It may be that the tableview's delegate/datasource are not set correctly. Could you check whether tableView:numberOfRowsInSection: and tableView:cellForRowAtIndexPath: are called or not?
It is not a good idea to show view of one view controller in another view controller view. Apple does not recommend it. what ever you want to do, do it in the same view controller.
To clarify on this ridiculous title:
I'm using my own subclass of JSQMessagesViewController (https://github.com/jessesquires/JSQMessagesViewController) - let's call it ACMessagesViewController. I'm loading my ACMessagesViewController through storyboard, by setting the storyboard UIViewController's custom class to ACMessagesViewController. I am trying to add a subview to ACMessagesViewController's view through the storyboard.
JSQMessagesViewController loads from a nib. When I add a subview to ACMessagesViewController's view through storyboard, the view disappears. The subview seems to be adding to a view other than my ACMessagesViewController's self.view, and by the time the viewdidload scope runs through, the subview is gone.
My questions are:
1. What is the proper way to add a subview (through storyboard) to a custom class UIViewController, when the UIViewController loads from a nib?
2. What is happening in this view loading process? Why is my subview (added through storyboard) adding onto a view that is not the same self.view in my ACMessagesViewController?
Thanks in advance!
I think it's one of those "if you need to work around it, you're probably doing it wrong" scenarios you so often hit in iOS development. :-) Really, if you want the functionality the JSQMessagesViewController provides, you shouldn't need to add additional views. But if you must add views, the "right" way to do it is to add them as subviews of whatever self.view is after you call super in viewDidLoad. If you don't want to construct views programmatically, you can put them in a separate nib (instead of the storyboard) and manually load them.
(Note: this is assuming viewDidLoad is getting called. If it isn't, you might need to hook into some other method.)
I used #Anna's suggestion to add the view in viewDidLoad but you don't need to use a second Xib or design the view in code.
What you need is:
A. Design your view in the your JSQMessagesViewController scene in the storyboard/xib file.
B. Create an outlet of the view you need to present.
C. In viewDidLoad add your view with view.addSubview(myView) (or [self.view addSubview:self.myView] for all the objc ones out there)
D. That's it!
I'm quite new to IOS so I'm sorry if my question is obvious.
I have set a ViewController's view in storyboard which contains other subviews.
In viewWillAppear I update these subviews depending on the object I passed to this ViewController. This object can have nil attributes and in this case I want to remove these subviews.
What is the right place to remove these subviews and is there a difference in terms of efficiency?
viewDidLoad
viewWillAppear
or viewWillLayoutSubviews ?
and will the constraints set to these removed objects also be removed?
Thx
The constraints will definitely be removed. However, it is possible to save the constraints in an array and add them back again in the future.
I would suggest making changes to the views( orientation, visibility, geometry ) in the viewWillLayoutSubviews method. You wouldn't want to do anything expensive in the ViewWillAppear method, because at that point the view is ready to be displayed to the user and it could impact how quickly the view appears to load for the user.
If you are using Storyboard and ARC do not worry about removing your views, conversely, if you are very interested to keep your memory under very tight control then do not use Storyboard and remove ARC.
What you refer to subviews are not subviews, the methods you listed are not UIView methods, and instead are UIViewController methods. However, if you have UIView objects that you are trying to remove, then those will also be handled for you. If you want more tight control, then declare them as public ivars, wrap them in #autoreleasepool {}, and set to nil in viewWillDisappear: or other method, or via delegate or notification pattern. It's relative to what you are doing and your conditions.
I'm getting the Unable to simultaneously satisfy constraints error.
I don't get the error when the viewcontroller establishes itself using viewDidLoad but it does get the error when using loadView...
Why is this happening?
I thought the only difference between loadView and viewDidLoad is that viewDidLoad occurs after loadView. At least, that seems to be the going explanation...
I don't know whether my answer would completely address your issue,but it might act as a starting point to resolve your issue.
There are quite a few points(you might be aware of) which needs to be noted before you use loadView:
loadView is a method that gets called when view is loading,viewDidLoad is method that will be executed after the
view is loaded.
loadView is recommended when you are willing to create the view programatically instead of setting in xib file,other wise there is
no point in using or calling loadView(It all depends on your
application requirement though).
Don't call super loadView if you initialise your view from story
board or xib file.
If you initialise your view from story board, do not call
[super loadView] and you must assign your rootView to self.view
property, if you call [super loadView] inside the method, you better never override this method and put your code in viewDidLoad method..
If you are using xib file to set up the view,do the modifications of objects set up in viewDidLoad and don't call loadView,if you are creating the view programatically,initialise the view in the loadView and do the additional set up in viewDidLoad.
The constraint error generally pops up in story board or xib file,when "Use AutoLayout" is selected,if you unselect it,the error disappears,since you are creating the view programatically in loadView,it is your responsibility to see to it that the auto layout option is disabled i.e. you need to make use of setTranslatesAutoresizingMaskIntoConstraints property by setting it to "NO".
You can also refer to some of related questions here and there which could well get you out of this issue.
Thanks and happy coding :)