Objective C - addobserver for UIView adding subviews? - iphone

Is there an easy way for listening for when a child or subview has been added to a UIView?
I've gone through the addobserver options and haven't found an obvious option anyway. There may be another option that would be affected though when content is added to a view or am I wrong in saying that? i.e. content width or height, positions, etc.?
Edit
This is accomplished easily using the advice of #Alkimake below (TextHolderClass).
I created a custom UIView subclass and set the UIView's class in Interface Builder to be equal to TextHolderClass
Thanks for your help, I know it should have been obvious :)

UIView methods may help you:
- (void)willMoveToSuperview:(UIView *)newSuperview

UIView has 2 methods to call after subview interactions. Simply create your custom UIView class and implement these methods which is pretty for you. And use your own CustomView
- (void)didAddSubview:(UIView *)subview;
- (void)willRemoveSubview:(UIView *)subview;

Related

iPhone SDK - Forwarding touches from a UIViewController to a subview

I have a UIViewController with a subclass of UIView on it called customSubView1. Then on customSubView1 I have another subclass of UIView called customSubView2.
I can capture all the events for touches on all the subviews when I put touchesBegan/touchesMoved/etc in the UIViewController class. But I want to be able to process them in my custom classes.
I keep reading that the UIViewController class needs to 'forward' the touch events to the subviews, but I haven't been able to find any example code to do this. Does anyone have any idea?
Many thanks,
Brett
Implement the touches... methods in your views.
Try to set for you UIView object userInteractionEnabled property:
myUIView.userInteractionEnabled = YES;

iPhone/iOS: Will there be called any method if a UIView is added as a subview

If I add a view as a subview like so
[self.view addSubview:mySubview];
Will there be called any method on mySubview, that I could override to add some custom behavior?
Adding a view to a (new) superview triggers
- (void)willMoveToSuperview:(UIView *)newSuperview
and
- (void)didMoveToSuperview.
See the UIView Reference for more.
You can override these two:
- (void)willMoveToSuperview:(UIView *)newSuperview
- (void)didMoveToSuperview
Take a look in the documentation for UIView for similar methods.
Yes, There is a method which get called if one change the superview . you need to override the below method in your subview class.
- (void)willMoveToSuperview:(UIView *)newSuperview
- (void)didMoveToSuperview
From UIView Doucumentation
willMoveToSuperview:,
didMoveToSuperview—Implement these
methods as needed to track the
movement of the current view in your
view hierarchy.
exep for special purpose is far better to customize you view in init phase, you have all you need and (more important) is a synchronous call.

iPhone: calling a parent/super method from a subview

hope someone can help me on this as been stuck for hours.
I am trying to make a kind of picture book.
I have a view which is my container and I add subviews to that by using addsubview.
On the subview, I have swipe gestures etc that I want to trigger off method in the parent view. I worked out how to trigger the delegate but I cant get the delegate to trigger the parent view. I have read over 10 different ways of doing it and none work.
I now very confused about what a super view is to. Just to confuse matters, the delegate has a tabcontroller and the parent view is tab button 1
I tried
[self.view.superview method]
[self.superview method]
On the delegate I tried
self.tabcontroller.parentviewcontroller, selectedview, super view.super
UPDATE :
The subview needs to be independant of the parent view as its a reusable view.
Also I have not set the parentview to superview as I just thought a superview is a view with subviews (please don't kill me). So maybe I just need to set the parentview to a superview?
The proper way of doing such things is to use protocol and delegate pattern.
Define a protocol like
#protocol subViewDelegate
-(void)somethingHappened:(id)sender;
#end
then implement that protocol in your superview :
#interface superView:UIViewController<subViewDelegate> {
...
}
...
#end
define a delegate property in your SubView like this
#interface subView : UIView {
id<subViewDelegate> delegate;
...
}
#propery (nonatomic, assign) id<subViewDelegate> delegate;
...
#end
the in your subview, call the delegate like this
[self.delegate somethingHappened :self];
It's a little hard to help you without any code given, but let's try:
Create a protocol: Name it however you like (I will call it "MyProtocol") and add to it the definition of the function you want to call in your superview, let's call it "respondToSwipe"
If your superview is a UIView, you have to create your own subclass of UIView and make your superview an instance of that class.
Let your (newly) created superview class implement the protocol of 1.) an implement the "respondToSwipe" method
Create an instance variable of the the type id in your subview, and name it however you like, e.g. "myDelegate".
Pass the superview created in 2/3.) to your "myDelegate" variable
Call [myDelegate respondToSwipe] whenever you like
For a custom view, you could subclass UIControl and use control events:
Define some control events. You're free to make up 4 control events (UIControlEventApplicationReserved = 0x0F000000)
Have whoever wants to receive events call addTarget:action:forControlEvents:
Have the control call [self sendActionsForControlEvents:events]
Alternatively, you could use a UIGestureRecognizer-style interface (addTarget:action:).
Alternatively just use UIGestureRecognizer (OS 3.2+)
Did your parent view set itself to be the superview of the subview when it added the subview? Otherwise the subview doesn't know who its superview is.
The more standard way of naming things to call the method handler the delegate instead of the superview, make it a property, and have the subview check for both the existence of the delegate being set and whether it can handle the method.
Here a very good example of how apply the delegation pattern on the iPhone. I downloaded the code an it works pretty good.
http://www.hivestudio.cat/index.php?option=com_content&view=article&id=57:technical-note-the-delegation-pattern-on-the-iphone&catid=35:technical-note-category&Itemid=76

iphone dev: UIImageview subclass interface builder - how to call custom initializer

I messing with iphone developement. I have a uiimageview subclass that I want to use to detect touches. I have sucessfully added to interfacebuilder and I can detect a touch in my UIImageview subclass within my application so all is good on that front. however my UIImageView subclass has a custom initializer which is not called when it is created in interface builder.
if I manually initialize the UIImageview and add it programmatically I think it will work but then I lose the ability to 'see' my positioning in Interface builder.
how can I either
1) 'see' a uiimageview in interface builder that is added in code? (not possible?)
2) call my custom initializer when the subclass is instantiated in interfacebuilder.
thanks
Hi thanks for suggestions. I think I'm getting closer to understanding the relationship between the xib and the viewcontroller.
I now am sucessfully adding my UIImageView subclass programmatically and using my custom initiializer which overrides InitWithFrame.
I think I read that the xib calls 'awakeFromNib' so I could equally add my iniitialization code in there. I like the idea of adding it programmatically as I have more control (although harderto set up my IU)
so one more realted question. if I add an UIImageView subclass in interface builder. I can see it and detect touches on it. if I want to refer to it in the view controller class do I have a pointer to it? i.e. is there a variable name for it? the UIImageViews I create myself I obviuosly know what they are called.....
You likely have put your instructions in the wrong initializer.
According to the documentation, objects unarchived from a NIB are initialized with initWithCode: if they conform to the NSCoding protocol; objects that don't conform to NSCoding are initialized with init.
In this particular case, UIImageView does conform to NSCoding. It's likely that you have you intended for initWithFrame: to be called and put your instructions in that method.
Can you not simply put your initialisation logic in viewDidLoad? In particular,
-(void)viewDidLoad {
[super viewDidLoad];
// Put whatever was in your custom initialiser here.
}

Change uitablelview properties in subclass in viewdownload method in cocoa?

I've been following a tutorial that manipulates a uitableview from a uiviewcontroller to generate nicely styled cells.
I was wondering is it possible to do same to a class that subclasses uitablewcontroller instead of uiviewcontroller. The user uses code like:
tableView.rowHeight = 50;
tableView.backgroundColor = [UIColor clearColor];
In the viewdidload method. I would like to do the same but again in a uitableview sub class. I tried to do
self.rowHeight = 50;
But this didn't work. Does anyone know how I can implement this?
Thanks a million!
This is the actual tutorial site: http://blog.atrexis.com/index.cfm/2009/1/6/iPhone--Customize-the-UITableCellView
The Cocoa design patterns encourage using a controller object to configure views, but there's no reason why you can't subclass like you're describing, especially if you need to add functionality that can't be done any other way. You can use properties and methods just how you're describing, so there's a problem somewhere else. What method are you subclassing to assign the row height? Have you checked in the debugger to make sure your subclass is being allocated instead of a regular table view?
A UITableViewController IS a subclass of UIViewController.
The only diffference is that it conforms to the UITableViewDelegateDataSource and UITableViewDelegate protocols and it has an additional instance variable: tablview.
In viewDidLoad, you can set any table properties you like except for style (style has to be set in the initializer or in IB)
- (void)viewDidLoad{
[[self tableView] setRowHeight:kCellHeight];
[[self tableView] setTableHeaderView:myView];
//etc...
}