Use iOS SwipeGesture To Cycle through UIButtons - ios

I have 6 UIButtons set up in my UIView, all in the exact same location. What I want to do, is to swipe from left to right or right to left, in order to go through the buttons.
I have the UIGestures all set up and working on the view, I am just not sure the best way to go about cycling through these UIButtons.
I was thinking that it could be simple enough to tag each UIButton and HIDE all but one, but am not sure about the best way to loop through these.

Just put them in an NSMutableArray and whatever button is at index 0 is the visible one, as they swipe you'd remove the button at index 0, set it to hidden = YES and add it to the end of the array then set the button at index 0's hidden = NO.
Assuming you're using ARC, inside your class' implementation (.m) file:
#interface MyFancyButtonClass () {
NSMutableArray *_swipeButtons;
}
inside your viewDidLoad:
_swipeButtons = [NSMutableArray arrayWithObjects:buttonOne, buttonTwo, buttonThree, buttonFour, nil];
buttonOne.hidden = NO;
buttonTwo.hidden = buttonThree.hidden = buttonFour.hidden = YES;
inside your gestureRecognizer:
UIButton *currentVisibleButton = [_swipeButtons firstObject];
UIButton *nextVisibleButton = [_swipeButtons objectAtIndex:1];
[_swipeButtons removeObject:currentVisibleButton];
[_swipeButtons addObject:currentVisibleButton];
currentVisibleButton.hidden = YES;
nextVisibleButton.hidden = NO;

Create a NSMutableArray like this:
NSMutableArray * buttons = [[NSMutableArray alloc] init];
[buttons addObject:button1];
[buttons addObject:button2];
[buttons addObject:button3];
[buttons addObject:button4];
[buttons addObject:button5];
Save this array to a property like this
self.buttons = buttons;
Store the currentButton Like this:
int currentButton = 0;
Get the current button like this:
UIButton * currentSelectedButton = buttons[currentButton];
Cycle through the buttons like this:
UIButton * currentSelectedButton = buttons[currentButton];
currentSelectedButton.hidden = YES;
currentButton++;
if (currentButton >= self.buttons.count)
currentButton = 0;
currentSelectedButton = buttons[currentButton];
currentSelectedButton.hidden = NO;

Related

Cleanest way to get associated UIView from UIButton press handler

In my app I have three UIButtons, each with an associated UIView. When one of the buttons is pressed, I want to:
Highlight the pressed button
Un-highlight the other buttons
Hide the UIViews associated with the other buttons
Un-hide the UIView associated with the pressed button
My solution (below) works and isn't horrible, but I can't help but think there's a cleaner, more efficient way. Any suggestions?
-(IBAction)buttonPressed:(id)sender {
NSArray *buttonArray = [NSArray arrayWithObjects:button1, button2, button3, nil];
NSDictionary* buttonViewDict = #{button1.titleLabel.text : view1,
button2.titleLabel.text : view2,
button3.titleLabel.text : view3};
for (UIButton* button in buttonArray) {
[button setHighlighted:[button isEqual:sender]];
[((UIView*)[buttonViewDict objectForKey:button.titleLabel.text]) setHidden:![button isEqual:sender]];
}
}
You can use the tag property to identify your buttons and views.
Set up the tag values in Interface Builder or in -viewDidLoad, then use the tag value to identify which button was pressed:
- (IBAction)buttonPressed:(UIButton*)sender {
for (UIButton* button in _buttons) {
button.highlighted = button.tag == sender.tag;
}
for (UIView* view in _views) {
view.hidden = view.tag != sender.tag;
}
}
For what it's worth, I like your way. I would consider using the buttons as the keys and simplifying it like so -
NSDictionary *buttonViewDict = #{button1 : view1,
button2 : view2,
button3 : view3};
[buttonViewDict enumerateKeysAndObjectsUsingBlock:^(UIButton *button, UIView *view, BOOL *stop) {
view.hidden = !button.highlighted = sender == button;
}];
You may also want to store the dictionary as a property.

Extend drop-down from a UITableCell to go over the cell height

In my table cells, there is a button that displays a drop-down menu when you click on it. The problem is, the drop-down menu exceeds the height of the cell and bleeds into the cell below.
In that case, if I click the item in the drop-down, it actually acts as I clicked the cell below.
I tried using the code below but it doesn't seem to work.
[super bringSubviewToFront:dropDown];
[super willMoveToSuperview:dropDown];
The function that shows the drop-down is defined in the custom class for the table cell:
- (IBAction)eventAction:(id)sender {
NSArray * arr = [[NSArray alloc] init];
arr = [NSArray arrayWithObjects:#"Hello 0", #"Hello 1",nil];
NSArray * arrImage = [[NSArray alloc] init];
arrImage = [NSArray arrayWithObjects:[UIImage imageNamed:#"apple.png"], [UIImage imageNamed:#"apple2.png"], nil];
if(dropDown == nil) {
CGFloat f = 100;
dropDown = [[NIDropDown alloc]showDropDown:sender :&f :arr :arrImage :#"down"];
dropDown.delegate = self;
dropDown.layer.zPosition = 1;
[super bringSubviewToFront:dropDown];
[super willMoveToSuperview:dropDown];
}else {
[dropDown hideDropDown:sender];
[self rel];
}
}
Any help is greatly appreciated!!
Thank you!!
Rather than being a case of views being on top of each other, I think it might be that the touch is being interpreted by the table cell below as well.
Try disabling user interaction in the table view when the eventAction is fired.
tableView.userInteractionEnabled = NO;
And then turn it back on when the drop down view is dismissed.

UIWebView only loads link after the second try

I've searched this issue for a solid amount of time, and I couldn't find an answer that solved my problem. If there are any similar questions that I missed and that have a working solution, please post a link to them.
Anyways...
I have a menu filled with buttons that, when clicked, opens up a UIWebView which opens a specific webpage. Everything works fine, but only after the second try. To be a little more clear, the first time I tap a button, the webpage gets stuck loading, but after you close it out and tap it again, the pages load up just fine.
Since I'm using multiple buttons, I decided to put them all in an IBOutlet Collection:
#property (nonatomic, retain) IBOutletCollection(UIButton) NSArray *btnArray;
I then set up an array that would hold all the buttons from the collection, set up a view controller for our webview class (we have a separate class for webviews, which has not caused me any problems in the past) and the webview's navigation controller, and finally I used a for loop to add all the buttons the array.
NSMutableArray *theButtons = [[NSMutableArray alloc] init];
webVC = [[WebviewViewController alloc] init];
webNav = [[UINavigationController alloc] initWithRootViewController:webVC];
for(int i = 0; i < [btnArray count]; i++)
{
UIButton *btn = btnArray[i];
btn.tag = i;
[theButtons addObject:btn];
[theButtons[i] addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
}
I also have set up an array with the end links of all the pages I need to go to, which will be appended to a url:
pages = #[#"exOne.php", #"exTwo.php", #"exThree.php", #"exFour.php", #"exFive.php", #"exSix.php"];
Note: all the above code in -viewDidLoad
Here is the method that handles what happens when a button is clicked:
-(void)buttonPressed : (id) sender
{
UIButton *clicked = (UIButton *) sender;
NSMutableString *url = [NSMutableString stringWithString:#"http://www.example.org/examples/"];
for(int i = 0; i < [btnArray count]; i++)
{
if(i == clicked.tag)
{
[url appendString:pages[i]];
[webVC loadURL:url];
webNav.navigationBar.translucent = NO;
webNav.navigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(backPressed)];
[self.navigationController pushViewController:webVC animated:YES];
}
}
}
If it wasn't clear from the method call
[webVC loadURL:url];
just sends the link to our webviewViewController class and loads the link.
Any ideas on why the webpages only load after the second attempt?
Your WebviewViewController has probably not been loaded when you call loadURL the first time. If the view controller is not loaded it's subviews and hence it's embedded UIWebView are not available. When you push the controller it gets loaded and the second time loadURL will work.

Cocos2D: Obtaining the text from a CCMenuItemFont

I guess I'm missing something obvious, but I simply can't figure out how to obtain the label of a CCMenuItemFont.
Background
I'm building a simple hangman game for the iPad. For entering the next guess, I've added 26 buttons to the UI (one for each letter of the alphabet) and wired them all to the same event handler.
Now, inside the event handler, I'd like to obtain the label of the button to update the current guess, but CCMenuItemFont apparently doesn't respond to text or label.
Problem
So - what method can I use to obtain the label of a CCMenuItem?
Code
Code for creating the buttons:
-(void)addButtons {
NSArray* charArray = [NSArray arrayWithObjects:
#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",
#"L",#"M",#"N",#"O",#"P",#"Q",#"R",
#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
[CCMenuItemFont setFontName:#"Marker Felt"];
[CCMenuItemFont setFontSize:45];
NSMutableArray* buttonArray = [NSMutableArray array];
for (unsigned int i=0; i < [charArray count]; ++i) {
CCMenuItemLabel* buttonMenuItem = [CCMenuItemFont
itemWithString:(NSString*)[charArray objectAtIndex:i]
target:self selector:#selector(buttonTapped:)];
buttonMenuItem.color = ccBLACK;
buttonMenuItem.position = ccp(60 + (i/13)*40, 600 - (i%13)*40);
[buttonArray addObject:buttonMenuItem];
}
CCMenu *buttonMenu = [CCMenu menuWithArray:buttonArray];
buttonMenu.position = CGPointZero;
[self addChild:buttonMenu];
}
And the event handler:
- (void)buttonTapped:(id)sender {
// Get a reference to the button that was tapped
CCMenuItemFont *button = (CCMenuItemFont *)sender;
[_guess addObject:[button text]]; // this throws an exception because text is the wrong method
[self paintCurrentGuess];
}
You're adding to your menu a CCMenuItemLabel, not a CCMenuItemFont (which actually extends the first one). In both cases, you need to access to the inner label containing the text.-
CCMenuItemLabel *button = (CCMenuItemLabel *)sender;
NSString *label = button.label.string;

Hide Multiple UIButton in single button click

I have 5 buttons in my xib, Button 1 to 4 is mapped to
-(IBAction)btn1to4:(UIButton *)sender;
Button 5 is mapped to
-(IBAction)btnFive:(id)sender;
Initially all the 4 buttons are hidden and only button 5 is visible, What I need is when I click on Button 5 all the 4 buttons should appear and when I click again on Button 5 they should disappear. For individual button I can write code in Button 5 as button1.hidden=NO, button2.hidden=NO and soon. But my buttons 1 to 4 are mapped to single btn1to4 method. How should I code in my btnFive method to hide/Unhide all 4 buttons at once?
Add buttons 1 through 4 to an IBOutletCollection in the interface builder. Add a property
#property (nonatomic, strong) IBOutletCollection(UIButton) NSArray *buttons1_4;
and drag buttons 1..4 there. Here is an answer explaining how to do it step-by-step.
Now you can operate all the buttons in that collection using a loop, rather than referencing them individually:
-(void)flipButtonsVisibility:(UIButton*)sender {
for (UIButton *btn in buttons1_4) {
btn.hidden = !btn.hidden;
}
}
Give tag of your button5 such like
button5.tag = 101;
In you button5's IBAction change id to UIButton * in parameter, such like
-(IBAction)btnFive:(UIButton *)sender
And Write following code
-(IBAction)btnFive:(UIButton *)sender
{
if(sender.tag == 101)
{
self.btn1.hidden = YES;
self.btn2.hidden = YES;
self.btn3.hidden = YES;
self.btn4.hidden = YES;
sender.tag = 102;
}
else
{
self.btn1.hidden = NO;
self.btn2.hidden = NO;
self.btn3.hidden = NO;
self.btn4.hidden = NO;
sender.tag = 101;
}
}
in your .h file
int a;
.m
-(void)viewDidLoad
{
a=0;
}
In your button click
-(IBAction)btnFive:(id)sender
{
if(a==0)
{
button1.hidden = YES;
button2.hidden = YES;
button3.hidden = YES;
button4.hidden = YES;
a = 1;
}
else
{
button1.hidden = NO;
button2.hidden = NO;
button3.hidden = NO;
button4.hidden = NO;
a = 0;
}
}
In your -(IBAction)btnFive:(id)sender, first check any one button (from 1-4) hidden property & do its opposite in condition. please find sample below -
-(IBAction)btnFive:(id)sender {
if(btn4.hidden==false){
btn1.hidden=true;
btn2.hidden=true;
btn3.hidden=true;
btn5.hidden=true;
}else{
btn1.hidden=false;
btn2.hidden=false;
btn3.hidden=false;
btn5.hidden=false;
}
}
try to write less number of line code and try to write effective lines.
If you need more help, please let me know. And if you find this answer suitable, Please vote me.
All the Best

Resources