Is it possible to add one UIButton object to multiple UIImageViews? - ios

I have a scrollView and inside this scrollView, there are various PFImageView objects.
I need a single UIButton object on every PFImageView (same place and same button) that will load a subView with the information of the image tapped.
Is this possible?

So, let me get this straight... You want to create only one button, place it on multiple imageViews and have it respond differently (depending on which imageView was tapped)?
In this case...
No, you can't have 1 button in N places.
But... you can create N button objects and have them all assigned to 1 single target method in which... you can have different functionality based on the button's tag.
PS: UICollectionView would be cleaner approach.

You can't have a single control in multiple locations, it's that simple.
I saw your comment about not wanting to use a UICollectionView because it's not the design you're looking for, but I wonder what kind of design you want to create with UIScrollView only because UICollectionView doesn't works.
UICollectionView is not restrained to line/grid display of cells, but can be customized in a huge amounts of ways. You should watch the WWDC 2012 video "Introducing Collection Views" : at the end of it, some UICollectionView possibilities are shown and some of them are quite impressive.
Also, https://www.cocoacontrols.com/ website is a good place to find custom controls and even inspiration for your own design.
This is a little digression from the original issue, but I really think that a collection of UIImageView within an UIScrollView can be created with a UICollectionView, especially if you want to add some controls within your "cells".

Yes. You should use specific control events when adding actions to the button.
E.g. in my application i record/stop/cancel sound as long as user hold a button (drag out to cancel).. like a walkie talkie phone...
[recordButton addTarget:self action:#selector(recordStart) forControlEvents:UIControlEventTouchDown];
[recordButton addTarget:self action:#selector(recordStop) forControlEvents:UIControlEventTouchUpInside];
[recordButton addTarget:self action:#selector(recordCancel) forControlEvents:UIControlEventTouchDragExit];

Related

Custom UITableViewCell Edit View

I've been looking over countless questions and answers here on SO, but could not find one that would provide the answer for my specific problem.
In a nutshell: I am trying to implement a custom edit view for my UITableViewCells. I would like to keep the basic "delete" and "rearrange/drag" actions (although on opposite ends than in the default implementation and with custom icons), and I would also like to add a "duplicate" action to them and one that navigates to a specific view (separate from the one when you click the cell in normal state). Something like this:
Ideally, I would like to trigger this edit mode on all cells when I toggle edit mode with a separate button, and on individual cells with a left swipe (without the drag option if it is not possible on an individual cell).
I have sub-classed UITableViewCell and was able to add a swipe recognizer that reveals a view ("cellOptionsContainer") with the 3 custom buttons on the right, all of which I was able to make work using tags and delegates, but that is most certainly not the right way to do things because I've added them to the cell's content view (not knowing any better):
// Add container to hold options buttons
cellOptionsContainer = [[UIView alloc] initWithFrame:CGRectMake(cellWidth,
0.0f,
(dataBase.sizeInteraction * 3),
dataBase.sizeInteraction)];
[self.contentView addSubview:cellOptionsContainer];
// Add edit button
UIButton *cellOptionsButton = [[UIButton alloc] initWithFrame:CGRectMake((0.0f),
0.0f,
dataBase.sizeInteraction,
dataBase.sizeInteraction)];
cellOptionsButton.tag = cellID;
[cellOptionsButton setImage:[UIImage imageNamed:#"iconEditOutlined"] forState:UIControlStateNormal];
[cellOptionsButton setShowsTouchWhenHighlighted:YES];
[cellOptionsButton setAdjustsImageWhenHighlighted:NO];
[cellOptionsButton addTarget:self action:#selector(presentEditView:) forControlEvents:UIControlEventTouchUpInside];
//[cellOptionsContainer addSubview:cellOptionsButton];
[cellOptionsContainer addSubview:cellOptionsButton];
Meanwhile, I was also able to make work the standard edit view in my UITableView delegate (rearranging and deleting both works fine), but I was unable to augment this standard edit view with the added functionality and visual customization illustrated above. I cannot even find a way to change the standard icons...
Any help would be much appreciated; although, I am looking for Objective-C answers as I do not know Swift! I am also doing everything programmatically; I do not use interface builder.

Tab Bar controller with code or with template?

I want to create an iOS app which will have use a Tab Bar controller. I know you can set this up by a template within XCode or you can just code it straight, but I'm unclear why use one approach over the other? other than I presume the template allows you to use the interface builder? if I don't want to use interface builder (and I don't) is there any point to using the tab bar app template? can I use the template but remove the interface builder bits? or if I'm doing that I might as well not use the template and just code the controller directly?
As board as the question sounds, let us look at it as a design decision and personal preference.
The Interface Builder allows you to design your layout quickly while providing you the visual bits - you know, how it would look like while designing it.
Can you achieve the same result programmatically? Yes, sure, if you can see it (where the UI element is, the color, the position it has in relation to the other elements, etc etc) while designing in your mind.
Let's say you wanted to have a UIButton, just a button, plain and have it hooked to a method called clicked when pressed. In IB you could achieve that within seconds.
Comparing that to doing it programmatically:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"play a beep" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0f, 80.0f, 40.0f, 40.0f);
[self.view addSubview:button];
You could do it either way - in IB or in code.
For the above case, would doing it in IB faster? Yes. But it doesn't prevent you from also doing it programmatically - it's your preference.
This serves to provide a general answer; because there are many cases involved while designing the interface as to whether one should use IB or do it programmatically.
Can you remove the IB bits? Yes.
Analogy:
Take it as buying a car and pimp it up with fog lamps, have it re-painted etc.
But if you decide to pimp your own ride by replacing every single bits on the car you buy, then why buy a car to do that and not just build one from scratch?

What methods to call for handling events for UIObject?

Is there a pattern Apple follows for which methods to call for handling an event for a UI objects?
What I mean is, to set an action for UIButton is [button addTarget:action:forControlEvents]
and for an ImageView I have to [imageView addGestureRecognizer]
I can never remember what methods to call. Is there an easy way to remember?
The "pattern" is that it is normal behavior for a button to respond to control events while it is not very common for an image view to respond to user interaction. Normally if you want to have a tappable image, you would use a UIButton and set an image on it. Apple decided to write the control events into UIButtons but not normal UIViews or UIImageViews.
So basically, you can use a control event if it is a button, otherwise you must use a different method. For normal views, gesture recognizers are a good option.

Single Tapping not being detected on dynamically created uibuttons

It was necessary to create a subclass of UIButton, lets call it subButton. These subButtons are instantiated one by one and dynamically added to an UIScrollView object.
Unfortunately the subButtons aren't reacting as expected. After scrolling away from the first dynamic generated subButtons and then returning back to them. They loose their reactivity to single tapping. I can not explain this behaviour. Can somebody explain why its behaving this way?
Many thanks.
Source code
self.subButton = [[SubButton alloc]initWithFrame:CGRectMake(69.5, y, 201, 114)];
[self.subButton setBackgroundColor:[UIColor blueColor]];
self.subButton.imageData = imageData;
self.subButton.videoPath = videoPath;
self.subButton.vidIndex = _indexVideo +1;
[self.subButton drawVidPreview];
[self.subButton setTag:(_indexVideo +1)];
[self.subButton addTarget:self action:#selector(handleSingleTap:) forControlEvents:UIControlEventTouchUpInside];
[self.videoScroll addSubview:self.subButton];
[_videoPreviews addObject:self.subButton];
The subButton method drawVidPreview adds some subviews to itself.
Do the buttons not respond at all, or just not to single-tap? That might help us help you.
If they don't respond at all, I would check your view hierarchy to make sure no other view (perhaps invisible) are sitting above your buttons. Or, perhaps are the buttons not being added to the parent view you think?
Please make sure you are not adding the same UIGestureRecognizer instance to all of the UIButtons, instead for each UIButton you need to add a separate instance, however all gesture instance can point to the same target.
At last, i could solve the problem. The reason why the first subButtons did not respond to single tapping with UIControlEventTouchDown is because the uiScrollview content offset was set to a negative y value. This first of all was not necessary and was done out of pure laziness. I corrected it by giving it a positive value.
So my conclusion is, if you do not set the content offset or content size of the scrollView correctly, some dynamically added buttons to the scrollView might not respond to tapping appropriately. This is even the case if all Buttons are placed completely on a uiScrollview object.
This I could confirm by playing around with the content size of the uiScrollview instance too. I changed size of the y value of uiScrollviews instance just by few points and then some of the last buttons did not respond to tapping anymore.
Just by increasing the content size of the y value again, made the buttons responsive again.

How can I create a dynamic overlay for a UIButton?

My application has a few portions that have really big buttons (640x130, 230x150, etc.) What I need is to have a way to update different portions of the button, with different text. Initially, I assumed that in my code I could create various UILabels and then add them as subviews to my button. However, as soon as I try to add a UILabel to the button as a sub-view, my app crashes.
What is the easiest way to create an overlay for a button, that I can completely layout myself, without preventing button taps from being interested using overlay controls?
I imagine there are multiple ways to solve this problem. However, the best solution for my case should use the fewest lines of code (I have quite a few of these types of buttons) and I'd like to be able to continue using some form of configurable button within IB.
I'm not opposed to subclassing UIButton but, if I do, I would like to be able to use it in IB. I've never created a custom UIView for such a circumstance, so I'd need help defining that type of subclass so that it will work correctly in IB.
You need to add the subview to the containing view - not the button. To ensure that is doesn't interfere with button presses, be sure to set it to:
[myCustomTextOverlay setUserInteractionEnabled:NO];

Resources