Infinite loop when adding CATiledLayer to UIView - iphone

I have a UIView in which I add a CATiledLayer and implement 'drawLayer'.
If I use a UIViewController and add the layer to a new subview of the controller, then everything is ok.
If I however try to use a UIView to and do all the craetion and drawing within this, then I get a infinite loop at the point shown below when I add this view to a superview.
0x002cfafb <+0425> ja 0x2cfa23 <-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]+209>
What am I missing?
Update:
By removing 'layer.delegate = self', the code no longer crashes...

Just found this:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/18121-calayer-interesting-crash.html
"You can't set the delegate to be the same as the view's layer's delegate, which by default is the view itself"

Related

how does a subview of a scrollview know the scrollview is being scrolled

I placed a few uiimageview objects into a scrollview. How can the imageview know the scrollview is being scrolled? Since the imageview is a subview of the scrollview i can't set the scrollview delegate to the imageview.
I want to create something similar to the apps view on the iphone. Where you can hold down an app and then drag it, but if you hold and move your finger too far to the left or right the action is stopped and scrolling takes over.
"Since the imageview is a subview of the scrollview i can't set the scrollview delegate to the imageview."
And why not?
You have viewcontroller which shows the particular scrollview correct? this viewcontroller should be the delegate of the scrollview, and viewcontroller should also hold pointers (either explicitly in an array or through tag of some sort) to the uiimageviews.
Then, whenever scrollview notifies viewcontroller (through scrollviewdidscroll type of delegate method), implement your logic to update uiimageview.
To implement the exact touch sequence, you can subclass UIGestureRecognizer or write your own touch handler.. take a look at Apple's documentation on Event Handling Guide :
http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009541
It doesn't, it just draws and draws. The scrollView makes sure you only see the part you really want to see
You might want to look at three20, they have a class that is very similar to the springboard. -- Used in facebook.app
Thanks Everyone, but I found out that UIScrollView sends the touchesCancelled message to the subview when scrolling starts.

layoutsubviews only called once despite any device rotation

just what the title says: I create an empty UIView subclass and I add a subview to it, I create an empty layoutSubviews method and I add a breakpoint there. Then I build the project and the simulation stops when loading the view at that point in the layoutSubviews method. Everything is fine so far. I continue the simulation and I rotate the device (assuming that the view controller is set to allow any orientation) but layoutSubviews is never called again, despite I can see how my object is rotating.
Any idea?
OK, i will simplify my question: How do I create a custom UIView with some subviews and make it responsive to the device orientation? I don't need to use drawRect or anything, just subclass UIView, add a couple of subViews and handle them when the device is rotating.
Did you try setting the autoresizingMask on the UIView? For example like below:
someView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
From the UIView documentation:
'When a view’s bounds change, that view automatically resizes its
subviews according to each subview’s autoresizing mask'
If you set the autoresizingMask to something other than None it should mean that the layoutSubviews method is always called when the views bounds change.
I'm not sure if it's exactly the same but i ran into a similar problem. I was using a UISplitViewContoller (template from Xcode) and adding a subview into the DetailViewController. The layoutSubviews methods was not getting called on rotation because it was a subview of the main UIView in the ViewController. So i added this to the DetailsViewController to get it to work (detailView is my subview):
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
if (detailView != nil) [detailView layoutSubviews];
}

Why does animating a subview cause its parent view's layoutSubviews method to be called?

I'm doing UIView animation on individual subviews that have a number of sibling views that I don't want affected by the single-view animation. However layoutSubviews is being called on the containing superview when I do the animation, causing the other siblings to be rearranged as well.
(I should explain that I'm doing initial subview layout in the parent view's layoutSubviews method; I only want it to be called the first time I'm setting up the subviews, not when I'm animating them individually later on.)
Why is the parent view's layoutSubviews method being called when animating its subviews?
I can imagine "sorting a grid of icons", you'll just have to animate one icon and the rest works automatically.
On the other side: What autoresizing masks do you have set for the view you're animating? Perhaps it has to do with that. What type of UIView are you animating? Perhaps it changes shape and thus calls [self.superview setNeedsLayout] to tell the superview that it changed shape.
Other idea: Has your superview "autoresizedSubviews" set?
I've found that even setting transformations on the layers of a view can trigger the view's setLayoutSubviews. It took me by surprise too, but maybe just because I don't need the behavior right now. It might sometimes become handy, I guess…

UIView subclass creating its own UIButtons

I have subclassed UIView so I can draw some lines in it. In this UIView are a whole bunch of buttons which I decided to create as a method that drawRect calls after the lines are drawn. It works but sometimes only part of the button renders. If i remove the button creation and instead add the UIButton in the subclassed UIViews parent it works fine.
Is doing things like adding subviews in drawRect method a big no no or should I not do it all together in UIView?
yea that's a pretty big no no. drawRect is for adding stuff with CG, not views. It gets called repeatedly and unpredictably. Adding them in initWithFrame should be pretty safe though.

UIView Subview Does not autoresize on orientation change

In my iPhone app, I have a view controller with two views (essentially, a front & back view). The front view is the main UIView, and the back view is a secondary UIView which is added as a subview using [self.view addSubview:backView] when showing the back and [backView removeFromSuperview] when hiding it. However, when the orientation changes, I have the following issue: the main UIView (frontView) rotates & all of its elements resize properly, but the secondary/subview UIView (backView) does not rotate & all of its elements do not resize properly. Does anyone have suggestions on how to make the secondary UIView autoresize properly according to the rules I have set in Interface Builder?
In the end, the solution I found was simply to separate my UIViews into separate UIViewControllers, and make sure that any views that I wanted to be able to rotate only had one UIView.
If I understand correctly, at the time of rotation 'backView' has been removed from it's superview, yeah? If so, that's the cause of the problem. The autoresize property determines how the view resizes relative to it's superview. If it doesn't have a superview it won't resize.
Perhaps using [backView setHidden:YES] instead of [backView removeFromSuperview] will be sufficient for your needs.
I had the same problem, here is how I fixed it based on imaginaryboy's
suggestions (thanks!)
Add the backview to the viewcontroller at viewDidLoad and hide it at the same time. Show it when needed, Hide it again. Set the resizing of the backview to UIViewAutoresizingFlexibleWidth in IB (or code I guess, I used IB)
Not that this is the same problem, but I found a similar problem when adding 2 subviews in my application:didFinishLaunchingWithOptions method. Since your reference above is using [self.view addSubview:view], I would understand that to mean that self is not your UIWindow. When adding an additional view controller to your App Delegate window (UIWindow), the second view controller will NOT receive any rotation events and will never rotate. Only the first view controller added to UIWindow will rotate. See:Technical Q&A QA1688 I believe this also affects views added after the first view where the first view is later removed from the superview.
I ended up following the suggestion I read elsewhere to use separate views for each orientation, thereby eliminating the need to worry about resizing behavior. As always, YMMV.
Or; if you want to avoid an additional controller, you can achieve the same effect by setting view.frame in willRotateToInterfaceOrientation:: like so
if(UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) ;//set stubborn view.frame for landscape orientation
else ; //set stubborn view.frame for portrait orientation
Although it feels like a hack; it's simple.