I have a collection view of labels and now need one with buttons, but it is not quite the same setting it up. I currently call the label collection view like this
[(UILabel *)self.EventTitles[i] setText:[object objectForKey:#"name"]];
which works fine but set text is not an option for UIButton collection views so I need a slight alteration in which I can not figure out. Can someone help me out with this?
I assume that in the case of the UIButtons you want to change their title. To do that you need to use the following method:
- (void)setTitle:(NSString *)title forState:(UIControlState)state
In your specific case of a UIButton collection you can do the following:
[(UIButton *)self.buttonCollection[i] setTitle:#"yourTitle" forState:UIControlStateNormal];
Related
I have a UITableview as a contact list in which there are a lot of users. It has a thumbnail photo and profile details on each row. I want to make it like when clicking on thumbnail, it goes another page for photo and when clicking on the rest of the space it goes to somewhere else. By using table view delegate I know which row is clicked and pass data, like user id to a new ViewController. But can I know which row when the thumbnail is clicked?
I am using the tag to find the view from cell, like
UIImageView *thumbnailView = (UIImageView *) [cell viewWithTag:1];
I think I cannot label the row index by tag.
You can add gesture to thumbnail image and get events on it. Need to set tag for thumb image as per indexPath.row.
Add following code in you in cell datasource method (cellForRowIndexPath:) :
cell.YOURIMGVIEW.userInteractionEnabled = YES;
cell.YOURIMGVIEW.tag = indexPath.row;
UITapGestureRecognizer *clickable = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageClicked:)];
clickable.numberOfTapsRequired = 1;
[cell.YOURIMGVIEW addGestureRecognizer:clickable];
[clickable release];
And also used below method :
-(void)imageClicked:(id)sender
{
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSLog(#"image tag is = %d", gesture.view.tag);
////////
You custome come goes Here !!!!!!!!!!!!!!
///////
}
You can use the photo as accessory view. Or use a UIButton with the photograph as background and set the action accordingly. (e.g. call a method on the view controller which then performs the push or segue. Doing so you will have to pass some data to the view controller indicating which row was actually clicked in. The number of the row can be used or you can set the tag of the button with some numeric id.)
Go the Easy way because doing it hard-way won't grant you a president award, right ?
Instead of UIImageView take a UIButton and set the Image on UIButton instance.
Set Button tag as the indexPath.row so that when you retrieve it you know which row is clicked. You can also sort it the other way but it seems quiet handy.
Add target into the button to a custom function. [ btnObj addTarget ...... ]
tyepcast you sender to a UIButton and receive the tag (indexpath.row)
You can remove all gesture recognizers and buttons in tableviewcell, and in your controller, you can implement below delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
To make this method triggered, you need to set tableview delegate as your controller, either via code as below, or using storyboard.
- (void)viewDidLoad {
self.tableview.delegate = self;
}
By doing this, it won't matter which item you clicked in your cell, delegate method will be called always.
I hope this helps.
I need to show one view or another in a single function.
Is there any way to do this without doing:
[label1 setHidden:YES];
[label2 setHidden:YES];
[label3 setHidden:YES];
e.g. in one function?
In android I would create two absolute layouts and show one or the other, I am searching something similar on iOS.
You can add those UILabel inside a UIView, and then when you need them to hide, you can set that UIView to be hidden.
You hide all subviews in a single line.
[view.subviews makeObjectsPerformSelector:#selector(setHidden:)
withObject:[NSNumber numberWithBool:YES]];
Similarly if you want to remove all subviews you can remove them in single line
[view.subviews makeObjectsPerformSelector:#selector(removeFromSuperView)];
I have some UIButtons inside a UIScrollView. When the view first loads there are about 8 buttons showing in the UIScrollView, all these buttons are visible and clickable.
However, once I scroll, any button that wasn't there when the view initially loaded isn't clickable.
Given I have a function that creates every button programatically on view load, is it possible that the addTarget function isn't working? I create about 280 buttons at the start and add the UITouchUpInside event programatically.
--Edit--
This is more or less the code, called inside viewDidLoad function
for (int i = 0; i < numberOfButtons; i++){
//Display stuff here
MyButton *aButton = [[MyButton alloc] initWithFrame:CGRectMake(x,y,w,h)];
[aButton.titleLabel setFont:[UIFont fontWithName:#"QuicksandBook-Regular" size: 17.0]];
[aButton setTitle:[currentDisplayArray objectAtIndex:i] forState:UIControlStateNormal];
[aButton addTarget:self
action:#selector(didPressButton:)
forControlEvents:UIControlEventTouchUpInside];
[aButton setUserInteractionEnabled:TRUE];
NSLog(#"width of button = %f height = %f", [aButton frame].size.height, [aButton frame].size.width);
//I printed this to check the height and width were generated correctly.
[btnContainerView addSubview:aButton]; //UIView hooked up to storyboard
[buttonArray addObject:aButton]; //Array to maintain reference to all buttons
}
Remember, they all display correctly, its just the ones that aren't rendered in the initial frame don't trigger the "didPressButton" selector.
-- Edit --
After playing around, I think its some kind of issue with the UIScrollView it is in. Is this some kind of apple bug? I even tried adding the gesture recognizers in the scrollViewDidScroll function.
-- Edit --
Another interesting hint, If I make the UIScrollView bigger, I can click more of the buttons, if I make it smaller I can click less. It definitely has something to do with the first rendered buttons.
Maybe iOS says its initialising the buttons, but doesn't keep the selectors of all 200+ buttons in memory. Or has an inbuilt number of possible selectors/gesture recognisers per class.
Yay, I worked it out.
There was a UIView sitting in front of the UIScrollView that the buttons were being added to.
The views were the same size, but only the buttons that were inside the initial bounds (the UIView size) were clickable.
There was a UIView that I think was called btnContainerView or something. What was happening was the buttons were being added to this UIView instead of the UIScrollView.
I think the UIView was set as the delegate for the buttons because thats were they were rendered. So when the UIScrollView received an input the buck stopped there. Calling addTarget:self on the buttons would mean their target was added to the scrollView, but they were rendered onto the UIView. A confusing bug because you would expect the UIScrollView not to scroll and render properly but it did, its just the delegates for the selectors were getting confused.
Thanks everyone for the help, this was quite tricky because the buttons scrolled correctly (UIScrollView got touch input) but the UIButtons didn't get the touch input.
TL;DR; The solution was removing the intermeditary UIView as it was interfering
I hope that you are using gestures int the view controller, if so you can use the below code
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (([touch.view isKindOfClass:[UIButton class]] && touch.view.tag==<Btn_Tag>)) {
return NO;
}
return YES;
}
When using the gestures, gestures will respond first rather than the button action.So, this code will help to move the responder the button's action.
With a UIControl such as a UIButton you can use something like
myControl.state
to figure out whether the control is currently being pressed down.
However, I need to do the same with some UIBarButtonItems (which are not derived from UIControl), so that I can stop my table from editing while one of them is pressed down.
Here's my code:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
//other checks
for(int b=0; b<self.toolbar.items.count; b++)
{
UIControl *currentControl= [self.toolbar.items objectAtIndex:b];
if(currentControl.state==UIControlStateHighlighted)
{
return NO;
}
}
return YES;
}
Obviously, it doesn't work, since it assumes that UIBarButtonItems can be treated as UIControls, but how would I do what I'm trying to do here?
If you want more control over your UIBarButtonItems the best thing to do is to recreate them as UIButtons (using custom art, etc), and then use the -initWithCustomView of UIBarButtonItem to create button items from actual UIViews.
This will give you full access to the usual button interactions methods: the only downside is you won't get the nice bar button style by default, and you'll have to provide the art for this yourself.
I had a similar problem before. I couldn't fix it, so I moved on. Here is what I did:
Use ToolBar instead of navigation bar, then use UIButton instead of UIBarButtonItem inside the toolbar.
I added a bunch of UILabel views to a UITableViewCell's contentView, some of which may overlap. On tapping any of the labels, I want to trigger some actions. Also, I want to bring up the tapped label to the top.
Using a UITapGestureRecognizer on the labels, I can figure out which one is tapped and perform the actions. But bringing the tapped and overlapped label to the front does not work. This is what I am trying:
UILabel *foundLabel = ....; // find the label
for (UITableViewCell *acell in theTable.visibleCells) {
UIView *cellContentView = acell.contentView;
if ([cellContentView.subviews containsObject:foundLabel]) {
[cellContentView bringSubviewToFront:foundLabel];
NSLog(#"should bring to front...");
}
}
I do get the NSLog output above, so I know that the bringSubviewToFront is being called on the appropriate cell's contentView. But no change in the subview layout order.
Ideas?
One thing to explore is zposition on the uitablviewcell's layer.
This successfully put on tableviewcell in front of another for me:
cell1.layer.zPosition=3 ;//above
cell2.layer.zPosition=2 ;//below
bringSubviewToFront: didn't work for me either
Try insertSubview:belowSubview: where the latter subview is a super view such as tab bar, nav bar, table view.