Embedded UIScrollView not loading its subviews - ios

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.

Related

How do I read this statement from my Xcode Debugger?

When I transition between view controllers, the two latest ones I have created, in the debug, I am getting a large string that I'm not quite able to get to the bottom of.
Can anyone point me in the right direction/ help me to understand this and find the problem I've made?
I have compared all of my documents/view controllers to my working/non-error ones and can't find anything obvious.
2019-02-12 18:47:20.879463+1300 Techsupport[15324:9474292] <UIView:0x7ff96154a2f0; frame = (0 0; 375 812); autoresize = W+H; tintColor =UIExtendedSRGBColorSpace 1 0.149131 0 1; gestureRecognizers = <NSArray:0x600002c474e0>; layer = <CALayer: 0x6000021d42c0>>'s window is not equal` to <Techsupport.EslViewController: 0x7ff9618fd800>'s view's window!
It's easier to read if you take out all the details about the view:
Techsupport[15324:9474292] <UIView>'s window is not equal to <Techsupport.EslViewController: 0x7ff9618fd800>'s view's window!
It's hard to know exactly what's going on without seeing some of your code, but fundamentally the view that the error is complaining about (located at 0x7ff96154a2f0) belongs to a view hierarchy in a window that's different from the one that the view controller's view is in.
Here are some things to consider:
How are each of these views created?
Do you expect to have two windows? (Most iOS apps only have one.)
What are you trying to do with the view in question?
A good way to start is to set a breakpoint at the spot where the error occurs, and then work backward until you figure out where the view in question comes from.
As #Sachin Vas said, "it looks like you have a segue which is set to trigger automatically and also programmatically in the code." he was correct, I did have a mistake where I had called the function programmatically as well as automatically. Thanks for everyone's help!

UIView Doesn't Appear Immediately

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.

CALayer is not positioned correctly within the View

Context
I am using this simple library to make an intro/walkthrough for my app (TL;DR, horizontal paging view controllers). I currently have 3 pages setup.
In the 3rd walkthrough page, I have a custom CALayer that animates a circle in an endless loop. I'd like to add that layer to a UIView in order to lay it out the way I want in IB (via auto layout).
In viewDidLoad (for the 3rd page) I create the circle layer and set its frame to be the same as the view I positioned, assuming the circle would be in the same spot as the view:
for v:UIView in [view1!, view2!] {
var pulse = PulseLayer()
pulse.frame = v.frame
pulse.cornerRadius = v.frame.width / 2.0
pulse.masksToBounds = false
view.layer.insertSublayer(pulse, above: v.layer)
}
Problem
When I run the app in the iPhone 6 simulator, the CALayers show up OUTSIDE their UIViews (see below).
One thing I noticed immediately is the layers are not misplaced the same way--one is above its view, and the other is to the left. I am assuming this is related to the constraints on the views, but I cannot figure out how to fix it.
Equally baffling to me is that when run on the iPhone 5 simulator, the layers appear exactly as I expect them to (see below).
I feel like I am misunderstanding some of the concepts at work here. How can I get the positioning to act the same? (Like the iPhone5 gif.)
Or, is there a better way to do what I am trying to do?
viewDidLoad is too soon. Remember, viewDidLoad is way early; the view is not in the interface yet and nothing has its ultimate size/position. If you're going to add the layers to view rather than as sublayers of the little views, you will have to run your layer-creation code much later, in order to get the position right. viewDidAppear: or viewDidLayoutSubviews will be safe - but of course you must use a bool flag so you don't do it too many times.
Personally I don't see why you don't add the layers to the little views. So you would just set pulse.frame = v.bounds and add as a sublayer to v, not to your view. It solves the positioning and gets the relationships right. And doing it in viewDidLoad would work, because when the views move, the layers move with them.

iOS 7 status bar overlaps with view - did they have to make it like this?

I know this has been asked before, but none of these solutions work, and that's the reason of my posting. Please do not close before considering my case.
My plist already has UIViewControllerBasedStatusBarAppearance = false.
I have already tried applying deltas, but to no result.
Changing the top level view frame in ViewWillAppear (like self.view.frame) did not succeed.
I thought of increasing the view height (storyboard attribute inspector), in combination with deltas, but my top level view X, Y are disabled in storyboard attribute inspector.
My main view doesn't have any children views because I load them into main view either dynamically or load them from XIBs which are again shared by more than view controllers. These XIBs provide layout for both Portrait and Landscape. I don't know what approach is ideal for this kind of configuration, but I would like it better if solution lies along these lines.
This approach worked partially, but gave me inconsistent results.
What makes the solution tricky is the fact that I have to support all 4 orientations - this is something I handle in code via didRotate and willRotate delegates for my other views, but failing to do it for statusbar.
Please help...
Could this link be of any help?
You might have to use the new setEdgesForExtendedLayout: method to get this working consistently?
Also, have a look at these official docs if you haven't already done so.
I ended up writing my own function to shift my all subviews (remember, not top level views whose frame is fixated by IB).
It didn't spoil my work but imagine if this was the case for a very big project with so many screens, the limitations would have made it a nightmare.

How to size container view's child view to fit iphone 4 and iphone 5 screens

I'm trying develop my app for iphone 4 and 5. However I encountered problem with container view. My view looks like this:
Now, I tried to google a little bit, and found, that I can set size of my views in project settings by uploading picture in different sizes (so that all my views will get resized automatically). This is true for all my views except my container view.
So my second attempt was to size my view in appdelegate like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_window.frame = CGRectMake(0, 0, 320, [[UIScreen mainScreen]bounds].size.height);
}
This unfortunately did nothing to my container view.
Only solution I found so far, was to set height of my embedded table view, by setting it to 458 in size inspector in interface builder. This sets it to fit iphone 5 screen, however on iphone4 (and in simulator) it is too much and some of my rows are below screen (as I expected).
If anyone could help me, I'll be glad, because I really don't know how to deal with this problem ;)
Well I would look into your constrains and your origin settings, incase you made any changes without knowing. Here is an example:
Make sure the origin settings are set to the top left "dot" like in the image and check your constrains parents (Superview in this case). Tip: The key to editing constraints in interface builder is never to drag and drop anything once you've added it to the view. Move and arrange things by editing the constraints instead.
You can also turn off the Auto-layout and do it manually
Here is also a great article on auto-layout in interface builder and apples own documentation on Resizing the View Controller’s Views and children's views (which a container is).
My last tip before you either have to try my last solution (which is underneath) or get the answer from someone else, is to check your architecture settings.
If that does not help it might be caused by some unknown random error that is hard to find, and I would suggest that you try to clean your project first by clicking/holding down "Shift" "command" and "K", and if that does not work, just start a totally new project and copy all the code and files over to the new project. This should help since the problem that you have should not be accruing since it should be dealt with automatically, but seemingly random errors do accrue on occasions.
I hope one of the tips help you out, if not I'm sorry.

Resources