I can't get my head round - (void)playInputClick; - iphone

I have an inputAccessoryView for a UITextField set up, which is loaded from a XIB when needed (in the exact same way as Apple's KeyboardAccessory example).
I'm trying to get the buttons on it to click when pressed using the playInputClick function but I can't work out how. The Apple documentation says that I need to add add a delegate method to the view, but the view was created purely in interface builder so I don't see how I can do this.
Does anyone know how to make this work? There seems to be no example code of this method being used anywhere on the internet.

I've been having the same problem and finally figured it out.
If you implement the protocol in a UIViewController it does not work. It needs to be implemented in a UIView subclass.
So to get it working, I created a view in interface builder with a view controller. Then I added another class which is a subclass of UIView. This class implements the UIInputViewAudioFeedback protocol. Then in interface builder I went to the Identity inspector of my view and changed the class to my UIView subclass which implements the UIInputViewAudioFeedback protocol. And the keyboard click sound is now working.
My view controller is still calling the [[UIDevice currentDevice] playInputClick], all I did was move the code for the UIInputViewAudioFeedback protocol into a UIView Subclass and set my views class to my UIView sublass.

Assuming you are trying to do this in an inputAccessoryView:
In the .h file, indicate that you implement the UIInputViewAudioFeedback
#interface YourAcessoryView : UIView <UIInputViewAudioFeedback>
In the .m file, add this method to satisfy the protocol
- (BOOL)enableInputClicksWhenVisible {
return YES;
}
When a button is pressed, do something like:
- (void)buttonPressed:(UIButton*)sender
{
[[UIDevice currentDevice] playInputClick];
// do more stuff
}

You need to implement a view controller class, and in the interface builder assign the files'owner as this class. Connect the view controller's view to your view.
Once you have done that you can implement the delegate in the view controller.
Its pretty simple and straight forward. Basically your view will be a member of a view controller class.

Related

Xcode error on superview of custom object

I have a custom table view controller called pfTableViewController and a custom cell called customTableViewCell.
From inside my customTableViewCell I try to access an NSMutableArray of the pfTableViewController:
- (IBAction)changeEditing:(UITextField *)sender {
pfTableViewController *pfWin = (pfTableViewController *) self.superview.superview;
[pfWin.pfFields replaceObjectAtIndex: myId withObject: #"some text"];
}
I used superview twice because the first one calls the UITableView and the second is supposed to call the pfTableViewController but it doesn't happen, I get this error:
2013-04-17 09:48:38.017 webgopher[21757:907]
-[UIViewControllerWrapperView pfFields]: unrecognized selector sent to instance 0x1d590d90
Any idea what's happening here?
If I use one more superview, it accesses the UINavigationTransitionView, that's too far I think!
Using something like superview.superview on apple implemented views like UITableViewCell is a very bad idea. You are relying on the view hierarchy not changing. This kind of thing can break very easily between versions of iOS.
You are also assuming the table view's super view is an instance of your view controller. But the view controller instance is not a view and not part of the view hierarchy. Instead you are getting a private apple view which wraps the view controller's view.
You should implement some kind of delegate method on your cell which is implemented by the view controller. This way the view controller can be directly notified of your "changeEditing" event without you having to crawl up private view hierarchies.
You can't access to a controller directly from its view. You need to look for the first controller through the responder chain. This post may be useful.-
How to get UIViewController of a UIView's superView in iPhone SDK?

how to call add a view from NSObject class

I am working on an app where i am doing some code in a class which is derived from NSObject and in this class i want to call another class which is a UIView type class and add it above current view or if possible over window. Can someone suggest me how will i do it as i cannot call [self.view addsubview:view] from a NSObject type class?
Also i can not move from my current class as here i am doing act(uploading with progress view) which will take time. so i have to add subview over my current view from this class only.
and yes i have to remove that uiview also later on when uploading completes.
Thanks in advance
Sounds like you want to add a view to the window:
[[UIApplication sharedApplication].keyWindow addSubView:myView];
How about placing your NSObject class inside a UIView, and then keeping a variable that references that view (eg masterView). You could hook that up in Interface Builder to a view that contains the NSObject, or if you're not using IB, create a UIView before instantiating your NSObject-derived class inside it, and pass a reference to the NSObject class which points to the master UIView.
Then, when you want to add a new subview to the screen, call
[masterView addSubview:anotherView];

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.
}

Call a function in a UIViewController's UIView

I've created a view controller and the associated view using the interface builder. I'm trying to call a function that I added to the UIView from the UIViewController. I'm not sure how to call that function though.
I've tried
[self.view myFunction]
but that just makes my program crash.
Did you declare your IB outlets and connect the method to it?
Your view (more accurately nib)'s file owner should be set to your viewController class.
Unless your calling drawing functions and methods you shouldn't call anything on the view. You just don't need to.
Edit: grammar corrections.
How is the view getting initialized? Is it a custom view type? If your view is being initialized from a nib, make sure that the class on the view type is the class that has the method implemented.
It is probably crashing because UIView does not have a method named myFunction. In order to add myFunction to a UIView object, you need to subclass it.
I assume you have subclassed your UIView, and called it something like MyView. You also probably have subclassed your UIViewController and called it MyUIViewController. Therefore you may have:
#interface MyViewController : UIViewController {
MyView *myView;
....
}
Now you can call [self.myView myFunction];
That's one way. Another way may be:
[(MyView *)self.view myFunction];
This depends on whether myView is the first view in the hierarchy (or should be set up in your NIB files).