UIView Doesn't Appear Immediately - ios

I'm creating a UIView in one of my methods and going through all the steps of adding it to the view:
background1 = UIView(frame: CGRectInset(other.frame, -thickness, -thickness))
background1!.backgroundColor = aColor
background1!.hidden = false
container.addSubview(background1!)
This is included in a method I call in viewDidAppear(). In general, everything works perfectly. This view, however, appears noticeably later when opening the app the first time.
I can tell, from setting breakpoints before and after the above code, that background1 does not appear on the screen immediately after the code is executed, nor even in any place I've been able to set breakpoints.
I'm not doing anything else with the view—for some reason it takes surprisingly annoyingly long to load.
I have a very complicated (as shown by the >114 comments here) layout setup that's part AutoLayout and part programmatic and thus would like to just resolve this issue alone, if possible, without ripping up everything else.
I know that viewDidAppear() is, of course, called after the view appears, meaning the code executed should take effect then, but from what I can tell, background1 isn't even appearing at that point.
Additionally, as you can see in the first line of the code I posted, background1's frame relies upon that that of other, another subview. This view has its frame determined by AutoLayout. From what I understand, it's only guaranteed that the correct frame will be reported after viewDidLayoutSubviews()is called. (Incidentally, this is even called after viewDidLoad().)
I know I've already made a mistake by mixing AutoLayout and programmatic layout, but I'm hoping there's a way to salvage this. I do, in fact, remember, a time in a previous version when nearly the exact same setup was working perfectly. (Looking back through commits, though, I couldn't find it.)
To be clear, I guess I'm asking if there's a way to force the UIView to appear when the code is executed. I've tried calling the parent's layoutSubviews(), but that doesn't seem to work.
Thank you.

Related

What view-function to be used for repositioning view frame (to cover 20point status bad gap)

Lately Ive been working with moving my frame to make up for the 20point gap when the status bar is not showing in landscape mode. I have finally gotten what I want, yet there is one problem that kind of annoys me. Let me explain: First I was using a call in viewDidLoad to move the frame, but that doesn't do anything to the frame, because I suppose the frame gets drawn after viewDidLoad. So I tried placing my call in viewDidAppear. That works smoothly, but sadly the user "sees" the repositioning; you can watch the frame being replaced with the bare eye. So I was wondering if theres anything I can do to prevent this, any workarounds. (just for good explanation this call is to take care of view frame when the user updates/go to another view controller when already in landscape. I have other functions to take care of rotation; which obv works)
Any help appreciated. I tried to be as specific as possible.
Thanks!

UINavigationController keeps displaying popped view

So in an iOS app I'm using a UINavigationController as the root view controller. I then push a few ViewControllers on the stack, let's call them A, B, C and D.
Now if I try to pop D from the stack, I sometimes * run into the following problem:
After calling popViewControllerAnimated, the view of the topmost view controller (D) remains. If I display the stack however, it is displayed correctly, i.e. A-B-C is displayed and D is gone. The pop method seems to do just what it's supposed to but the view does not reflect this.
I have tried various other approaches, (popToRootViewController, popToViewController) instead but the behaviour doesn't change (i.e. the stack is printed correctly but D's view remains). I have called setNeedsDisplay on all views that seem to make sense.
After popping D, I can still push and remove other view controllers. The stack reflects those changes, the view does not. Also, D's view remains responsive, i.e. it is not frozen and the app does behave correctly in the background. All views are very simple, there are no tabbed views or the like, just a couple of labels and buttons.
I have read a number of posts on SO and elsewhere about people having similar problems but none of the solutions seem to fit here. Does anyone have an idea why this happens?
*_ I haven't been able to figure out under which circumstances exactly. I first thought it was because I am popping D very soon after pushing it, but it also occasionally happens when there is more time between push and pop.
Only reason i can think of where this might happen is if you are not doing that in a main thread. If you are doing it after some network call, then do make sure you are going back to main thread. Sometimes, app won't crash if you do UI work on background thread but rather will behave like what you are seeing!
The problem seems to have been one of timing. As I mentioned, the push and pop operations (of D) sometimes do happen rather quickly after one another. Adding a delay of 2500 ms solved the problem. Adding 500 ms did not (always). Since neither is acceptable to me, I switched to a custom container view controller and therefore didn't spend a lot of time on figuring out what the minimum delay would be.
Just as sidenote: Changing from dispatch_async to dispatch_sync didn't have any effect. The delay seems to be necessary either way.
Thanks for everyone's help. I'm going to close this thread - if someone can provide a more complete answer as to why things are the way they are, please post it and I'll mark it as the correct answer then.

Embedded UIScrollView not loading its subviews

I have perhaps a strange VC structure here that I just made a bit stranger, causing it to break
UIViewController (contains->) UIContainerView (embeds ->) UIScrollView (contains ->) UIView
I have the final UIView because I couldn't figure out how to make the scrollview adhere to certain size restrictions so I just added a "content view".
Problem is, now the "content view's" data isn't loading
The Logs for the contentview are:
<UIView: 0x81cd510; frame = (-306 0; 612 792); autoresize = TM+BM; layer = <CALayer: 0x81c2000>>
The Logs for the Scrollview are
<UIScrollView: 0x81e5e90; frame = (0 0; 0 0); clipsToBounds = YES; opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x81e67b0>; layer = <CALayer: 0x81e6060>; contentOffset: {0, 0}>
so it appears to not be loading... what gives? How to I make it load?
Edit to clarify:
All of these views were created though IB
Not using AutoLayouts (although that sounds interesting)
The NSLog methods are called in ViewDidAppear in the viewcontroller at the top of the view hierarchy chain. (Perhaps this is the issue?)
Edit: uploaded the project to github so that people can take a looksie
https://github.com/Pinwheeler/ChiroMatic.git
I spent quite a bit of time going through your project and, frustratingly, I was not able to deduce what was causing the problem. But I found I was able to fix the problem by recreating your PrintViewController and PrintContentViewController scenes (and I had to recreate both to fix the problem). I created a fork of your project and fixed the two scenes. I tried to annotate my changes in both the source code as well as the git repository commit comments, so hopefully you can follow what I changed. My fork is available at:
https://github.com/robertmryan/ChiroMatic
(Just let me know when you want me to remove that repo. I'm happy to remove it whenever you want, as I assume you don't want me to leave a copy on github indefinitely.)
A couple of observations:
You say that you're not using autolayout, but you are. (Go to the first Document Inspector tab on your storyboard and you'll see that "Use Autolayout" is checked.) That's fine if you want to use it (it's now the default in Xcode) but be forewarned that you lose backward compatibility to iOS versions prior to iOS 6 if you use it. Autolayout is powerful, but it can be tricky when you first start using it. It's your call.
In your PrintContentViewController, my most significant change was to use the standard view controller scene configuration (where the top level view is a UIView), and I made the UIScrollView a subview of that. Having said that, I don't think you needed the UIView subview of the UIScrollView (and it's problematic as you lose some scroll view functionality if you have that intermediate UIView), so I removed that, and made all of the labels and the like subviews of the scroll view itself.
You're using container views all over the place, but it strikes me that you're adding a level of complexity that's unnecessary. (And, by the way, you wouldn't have had the problem raised in your original question if you didn't use these container views.)
Custom containers are very useful when you want to abstract the logic associated with the container view controller from its child view controller. But you're not doing that here. Worse, you're going through all sorts of gyrations to grab the IBOutlet references of a child controller and updating the properties in the container controller. I'd heartily encourage you to reconsider your use of these container views and just excise them from your project entirely.
If you have a compelling need for the container views, fine use them (I love them and use them all the time), but I don't see any need for it here, and you're making life much more complicated for yourself.
Also, by the way, the use of the embed segue is an iOS 6 feature only, which can be an issue if you need iOS 5 backward compatibility.
Bottom line, I never was able to reproduce your problem when creating a new project and mirroring your storyboard. Nor was I able to eliminate your problem by any edits to your old PrintViewController and PrintContainerViewController scenes. I was only able to fix it when I recreated these scenes, and when I did that, it just worked.
I left your old scenes there (prefacing the segues with "old" so the storyboard wouldn't get confused), so maybe you can spend time figuring out what's wrong, but I don't see it. Maybe there was some bug in the storyboard that is evading me. Maybe there's some setting I'm not seeing. All I know is that when I just recreated it, copying your controls to my two new scenes, it just worked.
Personally, I'd advise cutting the Gordian knot, and just eliminate the container views altogether. Your code will be cleaner, and these sorts of issues are less likely to rear their ugly heads.
This isn't a satisfying conclusion (to not know what caused the problem), but at least it appears to be fixed. Good luck.

UIView with UIButtons not showing up prior to click or rotate

I've been banging my head with this issue for the last two days. Googled a lot but wasn't able to find the answer yet, so I decided to request some help here. Let's see if I get any luck.
I'm coding a reusable control that consists of an UIView with a variable number of customized UIButtons. I implemented initWithFrame:, initWithCoder: and drawRect: where the buttons (which are built prior to drawing) are actually added to the view. Everything is done programmatically since the UIButton content should be supplied when using the control, so there's no XIB for this UIView.
This UIView, let's call it CustomizableBarButton is then used in an UIViewController, let's call it MyTestViewController with a view on it, let's call it customizableBarButtonView.
MyTestViewController's GUI was set on IB where an UIView was tied to customizableBarButtonView (the class was matching accordingly).
MyTestViewController's is a pretty standard class except for the viewWillAppear: that initializes the buttons and passes them to the CustomizableBarButton along with some other options.
The issue is that everything works perfectly...except for the first time!
I mean, when I run the app on the simulator (I haven't tried it on the iPhone yet but I strongly believe that it's not an hardware issue) the MyTestViewController shows the customizableBarButtonView background but not the buttons. Now when you click on the place where a button should be all the buttons suddenly appear!
I'm puzzled since the CustomizablebarButton drawRect: runs before the strange "click n'appear" effect and the buttons are actually added to the subview.
Another hint that my help: if you don't click on the buttons (so you still got no buttons yet) but rotate the device they will also appear as if by magic!
It is probably something very simple but I'm missing it and I'm going nuts...
Can someone lend a hand on this, please?
Thanks in advance!
You said you're adding the buttons in drawRect:. Don't do that. You need to add the buttons in your init methods.

UIWebView's sizeToFit works only once

In my custom UIViewController I have two distinct UIWebViews for which my custom UIViewController is the delegate. In webViewDidFinishLoad:webView I call [webView sizeToFit] and I can confirm it gets called twice, one for each UIWebView. However, to my great dismay, it only seems to affect the first one that gets called, while the other one remains unchanged. Obviously both their contents exceed the bounds, so I expect them to be resized accordingly.
Now, after lots of hours spent on this issue, how am I even supposed to proceed to understand what's wrong?
EDIT: Alright, apparently the problem is that the view in which I put the second UIWebView is not visible on the screen when I call sizeToFit. Calling it with a delay after the view is shown results in the expected behaviour. Now I have to find a way to do this without showing it, because I need to to be visible at a later time. Ideas?
It seems that doing that on viewDidAppear works like a charm.

Resources