iPhone custom UIView bounds - iphone

I am trying to create a custom UIView that is stored in a nib so that I can position it using Interface Builder.
I have created a class called RippleView that extends UIView. I'd like to position this view as a subview using Interface Builder. To do so, I've dragged a new view into my existing view in Interface Builder and gave it the RippleView class identity. I then linked my RippleView outlet to the view I just created.
In the RippleView class, I've implemented initWithCoder which doesn't do anything other than call [super initWithCoder...]. In awakeFromNib I go ahead and initialize my code.
Now, for some reason, if I try to check the bounds of the RippleView in awakeFromNib, I get ridiculous values (0 width and 1081171968 height). These bounds don't change in drawRect, so I don't think it's an issue of the view not being initialized. I get similar values in my touchesMoved event handler.
I had no problems when I was programmatically creating the subview (initWithFrame). What could be causing the frame bounds to go haywire?

Solved! The issue had nothing to do with the code. The UIView bounds are floats and I was printing them as integers. It's things like this that separate the programmers from the dropouts :p

Can you post your initWithCoder: implementation? If you're not setting the value of self, or if you've misspelled initWithCoder:, you might see these sorts of problems. Have you tried setting a breakpoint in initWithCoder: to make sure it gets called?

Related

Touch detection problems with custom View inside UIView NOT UIScrollView

I was googling for a while and I found similar problems but when the custom View is inside a ScrollView, but that is not my case.
I have a custom view that consists of a UILabel behind a UITextField, so I can animate that label later.
The problem is that when I add a View in my ViewController and in the Identity Inspector I set the Class as my custom class, when I use the application the UITextField within my custom view does not receive the touches well and it takes time to gain focus and therefore to open the keyboard. The strange thing is that if I move that same arrangement of views to my main ViewController in Storyboard everything works fine. Why doesn't it do it when I place it using the described method?
I plans to reuse this custom view a lot, so putting logic and views in each ViewController is not an option.
Thanks in advance
Well, the problem was in the constraints of the container UIView. That means, the UIView in my main ViewController. The Height of the UIView was a little bit smaller than the space required for my custom view, so although my custom view seemed to draw correctly, it was not receiving the gestures correctly. The solution was simply increase the height to the correct value occupied by my custom View. Thanks a lot!

how do I ensure a custom UIView I have is repositioned properly after an orientation change of the iPhone

how do I ensure a custom UIView I have is repositioned properly after an orientation change of the iPhone?
Background
As a parent view I have a UIViewController with an XIB
I have a custom UIView which is used in this parent (inserted in the XIB via Interface Builder). It programmatically at init creates some UIImageView's and adds them via "self addSubview", and then positions them via "self addSubview:imageView1" type approach
So the questions are how do I ensure I get the correct layout of these as orientation changes. Specifically:
Where do I trigger any such redrawing of the custom UIView? (e.g. is there a method in the parent UIViewController I should be using to trigger from?)
When the trigger occurs how do I request the redraw of the custom UIView? Do I need a custom method I create myself like "relayoutCustomView"? or should I be able to use an existing method in the custom UIView, in which case do I need to make sure in the custom UIView that my layout code is in a particular method?
thanks
how's this for the answer - seems to be starting to work, not sure if it's the best way:
separate out the layout code in my custom view and put in a separate method and make this public
this method will be called from within the custom view "init" method upon setup
also now however create an "didRotateFromInterfaceOrientation" method in the parent, and from within here also call into the new custom view layout method mentioned in [1]
noted it had to be "didRotateFromInterfaceOrientation", as with the "didRotateFromInterfaceOrientation" method it didn't work as the self.bounds result hadn't yet changed
How does this sound? I didn't use the "setNeedsDisplay" anywhere...

Why does my UIView subclass not redraw after I call setNeedsDisplay?

I have a custom UIView which is a sub-view of a UITableViewCell. When the cell is drawn, so is my custom view, correctly calling drawRect: in my UIView sub-class. When the cell is reloaded, the view is drawn correctly (drawRect: is called).
When a certain event happens (eg timer), I want to redraw the view without having to reload the whole cell. (This is not the only view in the cell.)
However, when I call setNeedsDisplay on my sub-view, nothing happens.
I'm guessing that when my view's drawRect: is called, the resulting image is cached in a backing somewhere such that when I call setNeedsDisplay that backing is redrawn to the screen, but my drawRect: call is never called again.
Why is drawRect: never called again after the cell is created?
EDIT: The cell's subviews are created from from a nib. ie: a UIViewController is loaded from the nib and its view is added to the UITableViewCell.
I made a test case from scratch with a custom view that isn't loaded from a nib (created by code) and it works as expected: setNeedsDisplay results in a drawRect: call. It must be something that's either set up in the .xib file or something that happens differently to a view when it's loaded from a nib.
I just ran into the same problem myself. For me it was an issue with my XIB - I am subclassing a UIView though - so adapt accordingly. My mistake in IB was that I attached my controls to the "file's owner" instead of attaching them to the UIView. I'm sure that in my inexperience there is something larger going on - perhaps someone with a bit more experience can elaborate.
Hope that helps!

Overriding internal UIViewController methods because an internal method is giving me bugs

What are the consequences of overriding internal UIViewController methods?
[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] is giving me some problems. It resizes my frame to values I do not desire sometimes. I do not even know where it picks off the new frame's values (it is close to the size of the superview to where I am adding it, but is off by 2px). Reference: this question, which I also need some help with.
I tried defining an empty - (void)viewDidMoveToWindow:(UIWindow *)window shouldAppearOrDisappear:(BOOL)flag method in my view controller. Bug is gone. >.<
Does anyone know if overriding -viewDidMoveToWindow:shouldAppearOrDisappear: is ok to do? Or some other workaround?
Or, does anyone know when and why -viewDidMoveToWindow:shouldAppearOrDisappear: likes to change my frame dimensions sometimes?
Thanks in advance.
If you override that method you run the risk of getting rejected, it is undocumented. An approach that isn't against the rules is to override the setFrame: method of the view in the view controller though.
If you believe this is a bug, put together a minimal test case and submit it to http://bugreport.apple.com and potentially upload it somewhere that we can see exactly what is happening as well.
For the "why" part of your question; the frame can automatically change in two situations:
Your ViewController is part of a view controller hierarchy (Navigation or TabBar). In this case your parent ViewControllers do as they please with your views frame.
Your view allows autosizing and the parent view changes size. The thing to note here is that the size of the root view is changed to fit the screen, causing autosizing to happen for all subviews.
To find the exact culprit in your case you could set a breakpoint in the overridden setFrame:.

How do you update a secondary view?

Perhaps there's a better way to set this up so I'm open to suggestions.
But here's what I'm doing. I have a main UIView. On top of that I have a UIImageView and another UIView. When the UIImageView changes, I want to change the second UIView. So I have a class for it and the IB object's type is set to the class. In the .m of that class is a drawRect method that draws some rectangles. Also in the .m is a NSMutableArray property that is synthesized. I created an instance of that class in the controller of the main view.
The problem: despite the fact that the drawRect works fine when the app starts (as traced in the debugger,) when the UIImageView changes I call a "setNeedsDisplay" on the instance variable of the second view after updating the #synthesize'd array but the drawRect does not get called.
I think it has to do with instances. I wouldn't think threading would be an issue here. I just want to draw in a separate area of the screen based on an image also displayed.
OK, for those who see this and are having a similar issue...
It was indeed an 'instance' problem. I had created the secondary UIView in IB. I think because I had established a connection there, the code ran fine on startup.
The fix was to create the subview programmatically and add it to the main view. That way there was only the one instance. Updating the #synthesize'd array variable and the subsequent calls to drawRect (via setNeedsDisplay) went to the one instance of the secondary view, the one I had added as a subview to the main one. Problem solved.