How do I associate events with an image view? - iphone

I have an app with an image view. When the user clicks on this view I want to run some code which will change the colour of a label and then hide this view
I have everything setup in the interface, i.e. Outlets etc, but I dont see any events available to associate
Can anyone help or point me in the direction of a good tutorial asap please?
Cheers
Paul

You shouldn't use an image view for this, you should use a UIButton. ImageViews are designed primarily to display, not allow for interaction (which is why their userInteractionEnabled flag is OFF by default.)

Take a look at the documentation for UIResponder - all UIViews, including UIImageView, inherit from it. In turn, UIResponder defines a set of methods you can override to handle the kind of event you're looking at. Start by subclassing UIImageView (call it MyImageView), then override the touchesEnded:withEvent: method.
As Ben Gottlieb said, however, this may be kind of an abuse of the UIKit framework - just make sure the user interaction you're creating makes sense and conforms to good UI practices.

The last time I needed to do this I just used a button also. You can always set up the highlighted state so that it doesn't highlight when someone taps on it if that's what you're trying to avoid.
Note that the higher level UI "actions" are implemented in UIControl, so if all you need to do is track actions like "Touch Up Inside" then it's possible to avoid the event layer, create a UIView in Interface Builder, then change the class to UIControl. You should then be able to use the connections inspector and connect any of those control actions to whatever.
If you place views inside the UIControl and the subviews have "User Interaction Enabled" unchecked (that is, user interaction is disabled) then taps and such inside the UIControl just ignore those and fall through to the UIControl. So another way to do this if you needed to for some reason would be to create a UIView, change the class to UIControl, then place one or more UIImageViews, UILabels, or whatever you want in your generic UIControl view. You can then get actions from the generic UIControl as if all that stuff wasn't inside it.

Related

iOS Custom Control

I am building a custom control that looks like the one in the image below.
It will basically be a menu with a slider. The arrows will allow me to change the three days show on the slider track. Acoording to the day I select with the slider I want to change some views on the main screen (this menu will on the bottom of my page). So basically this is the only thing that I will "listen" in my main controller: if some day has been selected.
I have figured out all the code I will have to write, but I am not sure wether I should subclass UIControl or UIView. And if so, where should I write the code of my controller (changing the days, adding the drag effec, etc ) in the UIControl (UIView)? Or should I subclass UIViewController, and write there all the code there. (but if so, why should I subclass UIControl (UIView) in the first way).
So basically I want to know what extra files I need to create, besides the view interface of my custom control(which I did in the IB), where should I put the code (IBOutlets, IBAction methods) and how do I communicate with the main view controller (I set the main controller as a delegate of my custom control?).
Sorry for the long post.
Thanks
I recommend to subclass UIControl. Users of this control can do [yourControl addTarget:self action:#selector(someMethod:) forControlEvents:UIControlValueChanged]; to react to changed values. In your control, when you have determined that a new day has been selected, you call [self sendActionsForControlsEvents:UIControlValueChanged]; and voila, all interested classes will get informed.
Keep that control as self-contained as possible. This means, only give it as much logic as you need to, and nothing more. Think about how you use Apple provided UI elements: try to make yours as generic (if practical; use common sense here). In short: you should thrive to make this control generic enough that it could be useful to you in other projects or other places of your app.
The short answer is you should subclass UIControl and put all of the logic to draw the component and interact with the component there. UIControl inherits from UIView and adds target/action behavior. This way you can sendAction:to:forEvents: with UIControlEventValueChanged whenever the date changes.
You could alternatively implement a delegate protocol for when the user changes the selected date.
For example:
#protocol DateSliderDelegate <NSObject>
- (void)dateSlider:(id)slider dateDidChange:(NSDate *)date fromDate:(NSDate *)oldDate;
#end
You don't want to use a UIViewController since it's job is to manage higher-level views, like the screen that your widget is on. You'll use a view controller later when you are consuming your component and do things like set the date to display initially and listen for change events.

How to disable multitouch when having several views?

I created my own custom view that extends UIControl. This custom view has its own touch implementation. I implemented touchesBegan, Moved, Ended, and Canceled methods in it.
In the main view controller, I created several instances of this view. So in the screen, there are a number of custom buttons.
I want to disable multitouch in my app. If I click one custom button, then other buttons shouldn't respond.
Actually, it was easy to implement this. While I held some buttons, I could just make other buttons' userInteractionEnabled property to NO until I ended touch.
But the problem is that when I tap these several buttons at the same time, two or more touchesBegan methods work simultaneously, and message passing is messed up.
I tried to set multiTouchEnabled = NO and exclusiveTouch = YES, but it still didn't work.
How can I force to disable multitouch in my app?
Thank you.
You need to set exclusiveTouch to YES, not NO (which is the default anyways). The name of the property refers to the view being the exclusive recipient of any touch events for the duration.

Deselect UIButton on touch down outside

I have a UIButton that selects itself on UIControlEventTouchUpInside. It deselects itself on UIControlEventTouchUpOutside. I also want it to deselect itself when there is a touch down outside of the button. Is there a good way to do this without subclassing UIWindow and overriding -hitTest:withEvent:?
EDIT: I just found this question, which confirms my fear that there isn't a really clean way to do this.
This is not how buttons are supposed to work. They cannot be active if there is no touch active inside them. What are you really trying to implement? Maybe a UIBUtton is not the best choice here.
You can do this with your UIViewController by implementing the touchesBegan/Moved/Ended methods. If they detect a touch outside of the button, set its state back to normal. Take a look at Event Handling.
I solved this, and released the source. I didn't have to subclass UIWindow, but I did need to override -hitTest:withEvent:.

iphone interface overlay pass-through events

alt text http://www.davidhomes.net/question.gif
I'm farily new to iphone dev (<3 months on my free time) and I'm starting development of my second app.
From the image, I'm adding a number of UIViews as subviews to my main UIViewController.view, the number of Views to add varies based on user selectable data.
Each view contains several controls, a label, a UITextField and a Horizontal UIViewPicker.
For simplicity I put a (VERY ROUGH) mock-up here with only two buttons.
Because I want to improve the GUI, I want to overlay an UIViewImage as the top sub-views of the added UIView, something like in the image.
The question is on passing through the events to the objects below it. I've read somewhere that one way was to use clipping, but the actual shape is more complex than just an oval frame.
Somewhere else I read that one could add four UIImages, one at each border, which would let the events pass through this hole. Seems like a dirty solution to me (Although I'm sure it would work)
Any ideas about the best way to do this? Any links to a tutorial or recipe online?
Your help is appreciated
thanks
david
Have you looked at protocols? You can define protocols for your views or objects, and the users of that object (the subviews underneath for example) can implement the protocol, set itself as the objects delegate and when actions happen they will notified through the protocols. So for example
An AboveView will declare a protocol that declares methods when a certain gesture was senced by that view so something like
-(void)didMakeCircleGesture...
as a property the underneathview will have a delegate, so in your method that actually sence the gesture youll have at the end something like
[delegate didMakeCircleGesture];
in turn the delegate is the view underneath or something, and it will conform to the protocol defined by the AboveView, and as part of it it will have to declare the method didMakeCircleGesture, so as a result when one makes a circle gesture in the AboveView the underneath view that conformed to the protocol will be told of the event and it can take appropriate action

Architecting a visual grid of 'buttons'

I'm trying to design how to implement a relatively simple application.
I want to create a grid of 'squares' that cover an entire screen. Each square should have the ability to respond to touch events, and then have an on/off state. For example, if I touch an 'off' square, and then drag my finger across 10 other squares, I want them all to turn on. And vice versa.
I'm not sure of the memory overhead of just creating a grid of 150 buttons. Also buttons don't have a settable state, from what I can see. I was also thinking of subclassing UIView and implementing UIResponder methods. It feels like I should be creating an array of array of buttons (or subclass of UIViews), but I'm not sure if that's possible.
I'm assuming that I can tell what square I'm on by getting the location of the touchevent from the UIResponder methods. Do I need to create my own version of a myButton by subclassing UIView, and have a on/off state property, along with UIResponder methods, and then create an array of myButtons?
UISwitch is the only thing that does this at the moment, though some have had good experiences using the UISegmentedControl for this as well.
Beyond that, you'll have to change the style/color of a regular button or image in code, which is what a lot of application developers do so it looks and reacts exactly the way they want it to.
Unless you need more of UIView's event handling stuff, you'll get the best performance if you use a single view and give it a -touchesBegan:withEvent, -touchesMoved, and -touchesEnded methods. Then use a custom drawRect method to draw your individual squares in either on or off states. You could also use layers, but trying to lay out 150 views is asking for trouble.