I have 3 UIButton on the same tab.
The problem :
When I click on button1, button2 and button3 all of them got selected; however what I want is when I select (for example) button2, the other buttons be unselected (like radio buttons on html).
Any idea on how I can solve this issue ?
Here is my code :
- (IBAction)button1:(UIButton *)sender {
sender.selected = !sender.selected;
}
- (IBAction)button2:(UIButton *)sender {
sender.selected = !sender.selected;
}
- (IBAction)button3:(UIButton *)sender {
sender.selected = !sender.selected;
}
There are a couple of straightforward solutions. Maybe they are not optimal, but you can use them:
First solution:
Link your buttons with corresponding properties:
#property (weak, nonatomic) IBOutlet UIButton *button1;
#property (weak, nonatomic) IBOutlet UIButton *button2;
#property (weak, nonatomic) IBOutlet UIButton *button3;
In each action change the selected property for each button:
- (IBAction)button1Clicked:(UIButton *)sender {
_button1.selected = YES;
_button2.selected = NO;
_button3.selected = NO;
}
Second solution:
Add all your buttons in NSArray:
NSArray *buttonsArray = [[NSArray alloc] initWithObjects: button1, button2, button3, nil];
Then link all the buttons with one action:
- (IBAction)buttonClicked:(UIButton *)sender {
for (UIButton *btn in _buttonsArray) {
if (btn == sender)
btn.selected = YES;
else
btn.selected = NO;
}
}
Don't forget to make your NSArray accessible for all the methods of the class, for example by creating a corresponding property:
#property (weak, nonatomic) NSArray *buttonsArray;
Third solution:
You can change the tag property for each button (through Interface Builder or in code):
_button1.tag = 1;
_button2.tag = 2;
_button3.tag = 3;
Then link all the buttons with one action (just like in previous example):
- (IBAction)buttonClicked:(UIButton *)sender {
if (sender.tag == 1) {
_button1.selected = YES;
_button2.selected = NO;
_button3.selected = NO;
} else if (sender.tag == 2) {
_button1.selected = NO;
_button2.selected = YES;
_button3.selected = NO;
} else if (sender.tag == 3) {
_button1.selected = NO;
_button2.selected = NO;
_button3.selected = YES;
}
}
Fourth solution: (by #velmurugan-s)
Use one action for all the buttons and set their default state to selected = NO:
- (IBAction)buttonClicked:(UIButton *)sender {
_button1.selected = NO;
_button2.selected = NO;
_button3.selected = NO;
sender.selected = YES;
}
Summary:
I'd recommend you to use the second solution as the most optimal one.
What you can do is connect button1,button2,button3 to same button123 in interface section give them appropriate tags
- (IBAction)button123:(UIButton *)sender;
In its description use below code
- (IBAction)button123:(UIButton *)sender {
if (sender.tag == 111)
{
sender.selected = !sender.selected;
if (sender.selected)
{
self.button2.selected = NO;
self.button3.selected = NO;
}
}
else if (sender.tag == 222)
{
sender.selected = !sender.selected;
if (sender.selected)
{
self.button1.selected = NO;
self.button3.selected = NO;
}
}
else if (sender.tag == 333)
{
sender.selected = !sender.selected;
if (sender.selected)
{
self.button1.selected = NO;
self.button2.selected = NO;
}
}
- (IBAction)button1:(UIButton *)sender {
btn1.selected = YES;
btn2.selected = NO;
btn3.selected = NO;
}
- (IBAction)button2:(UIButton *)sender {
btn1.selected = NO;
btn2.selected = YES;
btn3.selected = NO;
}
- (IBAction)button3:(UIButton *)sender {
btn1.selected = NO;
btn2.selected = NO;
btn3.selected = YES;
}
You had change the selected sate for a button that you have selected,You need to change all other button state too.
Related
I'd like to know when BarButton items gets the accessibility focus or loses the accessibility focus and so I implemented the informal protocol methods of UIAccessibilityFocus but it's not still firing.
extension UIBarButtonItem {
override open func accessibilityElementDidBecomeFocused() {
if self.accessibilityElementIsFocused() {
print("My element has become focused.")
}
}
override open func accessibilityElementDidLoseFocus() {
if self.accessibilityElementIsFocused() {
print("My element has lost focus.")
}
}
override open func accessibilityElementIsFocused() -> Bool {
if (self.accessibilityIdentifier == "hamburger") {
return true
} else {
return false
}
}
I imported the swift file into viewcontroller as well
#import "Sample-Swift.h"
then I tried subclassing and implemented the methods that also didn't work
.h header file
#import <UIKit/UIKit.h>
#import <UIKit/UIAccessibility.h>
NS_ASSUME_NONNULL_BEGIN
#interface HamburgerButton : UIBarButtonItem
#end
NS_ASSUME_NONNULL_END
.m implementation file
#implementation HamburgerButton
- (BOOL)isAccessibilityElement
{
return YES;
}
- (void)accessibilityElementDidBecomeFocused {
if ([self accessibilityElementIsFocused]) {
NSLog(#"My element has become focused.");
}
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(#"My element has lost focus.");
}
}
- (BOOL)accessibilityElementIsFocused {
if ([self.accessibilityIdentifier isEqualToString:#"hamburger"]) {
return YES;
} else {
return NO;
}
}
#end
Here is the implementation in view controller
HamburgerButton *leftButton = [[HamburgerButton alloc]
initWithTitle:#"Hamburger"
style:UIBarButtonItemStylePlain
target:self
action:#selector(flipView:)];
leftButton.accessibilityIdentifier=#"Hamburger";
leftButton.tag = 88;
leftButton.isAccessibilityElement = YES;
HamburgerButton *rightButton = [[HamburgerButton alloc]
initWithTitle:#"Chat"
style:UIBarButtonItemStylePlain
target:self
action:#selector(flipView:)];
rightButton.accessibilityIdentifier=#"Chat";
rightButton.tag = 89;
rightButton.isAccessibilityElement = YES;
self.navigationItem.leftBarButtonItem = leftButton;
self.navigationItem.rightBarButtonItem = rightButton;
Even though the focus comes and goes away from bar button , I'm not getting the call back on accessibilityElementDidBecomeFocused
Any ideas what could be done to get accessibilityElementDidBecomeFocused firing ?
Update 1:
I could achieve this functionality by the means of notification observer but it's not giving enough information about the receiver of focus so couldn't differentiate one bar button from the other.
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(hamburgerGotFocus:) name:UIAccessibilityElementFocusedNotification object:nil];
and find the selector method below
-(void)hamburgerGotFocus:(NSNotification *) notification{
NSLog(#"Focus:%#",notification);
UIView *receiver = notification.userInfo[#"UIAccessibilityFocusedElementKey"];
if(receiver!=nil){
NSString *strElement = [[NSString alloc]initWithFormat:#"%#",notification.userInfo[#"UIAccessibilityFocusedElementKey"]];
if([strElement containsString:#"UIButtonBarButton"]){
}
}
}
Here is the log of notification
2022-10-12 18:57:03.992859+0530 Sample[32427:1579550] Focus:NSConcreteNotification 0x280ac9980 {name = UIAccessibilityElementFocusedNotification; userInfo = {
UIAccessibilityAssistiveTechnologyKey = UIAccessibilityNotificationVoiceOverIdentifier;
UIAccessibilityFocusedElementKey = "<_UIButtonBarButton: 0x10690fce0; frame = (0 0; 49 44); tintColor = UIExtendedSRGBColorSpace 0 1 0 1; gestureRecognizers = <NSArray: 0x2804262e0>; layer = <CALayer: 0x280afa9e0>>";
}}
Update 2:
I tried doing this with UIlabel using Category and subclassing both worked
#interface SampleLabel : UILabel
#end
#implementation SampleLabel
- (void)accessibilityElementDidBecomeFocused {
NSLog(#"accessibilityIdentifier:%#",self.accessibilityIdentifier);
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, #"sample label from subclass");
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(#"My element has lost focus.subclass");
}
}
- (BOOL)accessibilityElementIsFocused {
return YES;
}
#end
By means of category
#interface UILabel (SampleLabel1)
#end
#implementation UILabel (SampleLabel1)
- (void)accessibilityElementDidBecomeFocused {
NSLog(#"accessibilityIdentifier:%#",self.accessibilityIdentifier);
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, #"sample label from category");
}
- (void)accessibilityElementDidLoseFocus {
if ([self accessibilityElementIsFocused]) {
NSLog(#"My element has lost focus.Category");
}
}
- (BOOL)accessibilityElementIsFocused {
return YES;
}
#end
I'm wondering whether accessibilityElementDidBecomeFocused is not compatible with UIBarButtonItem ?
FYI:
I'm following this tutorial to implement accessibilityElementDidLoseFocus.
accessibilityElementDidBecomeFocused
is not firing for bar button but it's firing for UIButton. So I just created a bar button using UIButton like below and the problem is fixed
// Image
UIImage *img1 = [UIImage imageNamed:#"img1"];
// Button
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
[btn1 setImage:img1 forState:UIControlStateNormal];
btn1.frame = CGRectMake(0.0, 0.0, img1.size.width, img1.size.height);
btn1.tintColor = [UIColor greenColor];
[btn1 addTarget:self action:#selector(barButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
// Bar button
UIBarButtonItem *barButton1 = [[UIBarButtonItem alloc]initWithCustomView:btn1];
// Accessibility element
btn1.isAccessibilityElement = true;
img1.isAccessibilityElement = false;
btn1.accessibilityLabel = #"some accessibility text";
btn1.accessibilityTraits = UIAccessibilityTraitNone;
self.navigationItem.rightBarButtonItem = barButton1;
Every time I switch the UISwitch to either on or off in the simulator, it still returns false even when one of the switches is on. I even tried adding
self.switch1.on = true;
inside the if statement of checkSwitch1Changed.
This is my code in .m file.
- (IBAction)checkSwitch1Changed:(id)sender {
if (self.switch1.on)
{
self.switch2.on = NO;
self.switch3.on = NO;
self.switch4.on = NO;
}
...
}
- (IBAction)checkSwitch2Changed:(id)sender {
if (self.switch2.on)
{
self.switch1.on = NO;
self.switch3.on = NO;
self.switch4.on = NO;
}
...
}
- (IBAction)checkSwitch3Changed:(id)sender {
if (self.switch3.on)
{
self.switch1.on = NO;
self.switch2.on = NO;
self.switch4.on = NO;
}
...
}
- (IBAction)checkSwitch4Changed:(id)sender {
if (self.switch4.on)
{
self.switch1.on = NO;
self.switch2.on = NO;
self.switch3.on = NO;
}
...
}
This is my code in .h
#property (weak, nonatomic) IBOutlet UISwitch *switch1;
#property (weak, nonatomic) IBOutlet UISwitch *switch2;
- (IBAction)checkSwitch1Changed:(id)sender;
- (IBAction)checkSwitch2Changed:(id)sender;
//********
#property (weak, nonatomic) IBOutlet UISwitch *switch3;
#property (weak, nonatomic) IBOutlet UISwitch *switch4;
- (IBAction)checkSwitch3Changed:(id)sender;
- (IBAction)checkSwitch4Changed:(id)sender;
This actually works and sends back true if I send the data using that view controller. But I am trying to access this data from another view controller and it sends back false. I used this code to access the data from the other view controller.
//import data from SetupController'
SetupController *setupController = [[SetupController alloc] initWithNibName:#"SetupController" bundle:nil];
...
Firebase *postRef = [savedRef childByAppendingPath: #"Switches"];
NSDictionary *post1 = #{
#"Check1": #(setupController.self.switch1.on),
Did you try checking for the isOn property, instead of on?
if (self.switch1.on)
becomes
if (self.switch1.isOn)
Also check that the IBAction associated with the switch is a
ValueChanged
event, and that the reference outlets are properly linked.
You'll need to also 'set' the switch to on, rather than listening to see if it's on (without setting first, if that makes sense).
I'm sure there's a much more elegant way of doing this (it's a but long winded here), but you should get the idea and this method should work if you hook ALL the switches up to the one IBAction and changed the sender on the method from id to UISwitch.
(of course you don't need to use just the one IBAction, though it makes more sense if you do, as opposed to 4 actions all wanting to do the same thing)
- (IBAction)switchPressed:(UISwitch *)sender {
if (sender==self.switch1) {
self.switch1.on = YES;
self.switch2.on = NO;
self.switch3.on = NO;
self.switch4.on = NO;
}
if (sender==self.switch2) {
self.switch1.on = NO;
self.switch2.on = YES;
self.switch3.on = NO;
self.switch4.on = NO;
}
if (sender==self.switch3) {
self.switch1.on = NO;
self.switch2.on = NO;
self.switch3.on = YES;
self.switch4.on = NO;
}
if (sender==self.switch4) {
self.switch1.on = NO;
self.switch2.on = NO;
self.switch3.on = NO;
self.switch4.on = YES;
}
}
In my app I've to create a custom alert view like the following:
So I followed this tutorial to create a custom alert view. I finished it but I'm getting issue in the following method:
- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove {
NSMutableArray *items = [[NSMutableArray alloc]init];
[items addObject:self.buttonOk];
[items addObject:self.buttonClose];
int buttonIndex = (tag == 1);
if (shouldRemove) {
[items removeObjectAtIndex:buttonIndex];
} else {
if (tag == 1) {
[items insertObject:self.buttonOk atIndex:buttonIndex];
} else {
[items insertObject:self.buttonClose atIndex:buttonIndex];
}
}
}
I edited it than the tutorial because I don't need a UIToolBar for buttons. When I run the app it says me that I can't insert a nil object in an NSMutableArray, but I don't understand what's wrong, I hope you can help me to fix this issue.
UPDATE
Here's all the class code I developed:
#import "CustomAlertViewController.h"
#define ANIMATION_DURATION 0.25
#interface CustomAlertViewController ()
- (IBAction)buttonOk:(UIButton *)sender;
- (IBAction)buttonCancel:(UIButton *)sender;
#property (weak, nonatomic) IBOutlet UIButton *buttonClose;
#property (weak, nonatomic) IBOutlet UIButton *buttonOk;
#property (strong, nonatomic) IBOutlet UIView *viewAlert;
-(void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove;
#end
#implementation CustomAlertViewController
- (id)init
{
self = [super init];
if (self) {
[self.viewAlert setFrame:CGRectMake(self.labelAlertView.frame.origin.x,
self.labelAlertView.frame.origin.y,
self.labelAlertView.frame.size.width,
self.viewAlert.frame.size.height)];
[self.buttonOk setTag:1];
[self.buttonClose setTag:0];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)showCustomAlertInView:(UIView *)targetView withMessage:(NSString *)message {
CGFloat statusBarOffset;
if (![[UIApplication sharedApplication] isStatusBarHidden]) {
CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
if (statusBarSize.width < statusBarSize.height) {
statusBarOffset = statusBarSize.width;
} else {
statusBarOffset = statusBarSize.height;
}
} else {
statusBarOffset = 0.0;
}
CGFloat width, height, offsetX, offsetY;
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft ||
[[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
width = targetView.frame.size.width;
height = targetView.frame.size.height;
offsetX = 0.0;
offsetY = -statusBarOffset;
}
[self.view setFrame:CGRectMake(targetView.frame.origin.x, targetView.frame.origin.y, width, height)];
[self.view setFrame:CGRectOffset(self.view.frame, offsetX, offsetY)];
[targetView addSubview:self.view];
[self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.viewAlert setFrame:CGRectMake(0.0, 0.0, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView commitAnimations];
[self.labelAlertView setText:#"CIAO"];
}
- (void)removeCustomAlertFromView {
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[self.viewAlert setFrame:CGRectMake(0.0, -self.viewAlert.frame.size.height, self.viewAlert.frame.size.width, self.viewAlert.frame.size.height)];
[UIView commitAnimations];
[self.view performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:ANIMATION_DURATION];
}
- (void)removeCustomAlertFromViewInstantly {
[self.view removeFromSuperview];
}
- (BOOL)isOkayButtonRemoved {
if (self.buttonOk == nil) {
return YES;
} else {
return NO;
}
}
- (BOOL)isCancelButtonRemoved {
if (self.buttonClose == nil) {
return YES;
} else {
return NO;
}
}
- (void)removeOkayButton:(BOOL)shouldRemove {
if ([self isOkayButtonRemoved] != shouldRemove) {
[self addOrRemoveButtonWithTag:1 andActionToPerform:shouldRemove];
}
}
- (void)removeCancelButton:(BOOL)shouldRemove {
if ([self isCancelButtonRemoved] != shouldRemove) {
[self addOrRemoveButtonWithTag:0 andActionToPerform:shouldRemove];
}
}
- (void)addOrRemoveButtonWithTag:(int)tag andActionToPerform:(BOOL)shouldRemove {
NSMutableArray *items = [[NSMutableArray alloc]init];
[items addObject:self.buttonOk];
[items addObject:self.buttonClose];
int buttonIndex = (tag == 1);
if (shouldRemove) {
[items removeObjectAtIndex:buttonIndex];
} else {
if (tag == 1) {
[items insertObject:self.buttonOk atIndex:buttonIndex];
} else {
[items insertObject:self.buttonClose atIndex:buttonIndex];
}
}
}
- (IBAction)buttonOk:(UIButton *)sender {
[self.delegate customAlertOk];
}
- (IBAction)buttonCancel:(UIButton *)sender {
[self.delegate customAlertCancel];
}
#end
UPDATE 2
Code in which I use the CustomAlertView:
#import "PromotionsViewController.h"
#import "CustomAlertViewController.h"
#interface PromotionsViewController () <CustomAlertViewControllerDelegate> {
BOOL isDeletingItem;
}
#property(nonatomic,strong) CustomAlertViewController *customAlert;
- (IBAction)buttonBack:(UIButton *)sender;
#property (weak, nonatomic) IBOutlet UIButton *buttonAlert;
- (IBAction)buttonAlert:(UIButton *)sender;
#end
#implementation PromotionsViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.buttonAlert setTitle:self.promotionSelected forState:UIControlStateNormal];
[self.customAlert setDelegate:self];
isDeletingItem = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)buttonBack:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc]init];
[self.customAlert removeOkayButton:NO];
[self.customAlert removeCancelButton:NO];
NSString *message = [NSString stringWithFormat:#"La tua offerta %# del 20%% è stata convertita in punti IoSi x10", self.promotionSelected];
[self.customAlert showCustomAlertInView:self.view withMessage:message];
isDeletingItem = YES;
}
- (void)customAlertOk {
if (isDeletingItem) {
[self.customAlert removeCustomAlertFromViewInstantly];
} else {
[self.customAlert removeCustomAlertFromView];
}
}
- (void)customAlertCancel {
[self.customAlert removeCustomAlertFromView];
if (isDeletingItem) {
isDeletingItem = NO;
}
}
#end
Maybe you're calling addOrRemoveButtonWithTag:andActionToPerform: at a time where your UI is not fully created, since UI elements are created asynchronously. So if you call this method, right after custom alert view instanciation, you'll get your crash because the buttons in the view are not created.
To solve this issue, you need to call addOrRemoveButtonWithTag:andActionToPerform: only once your custom alert has been added to the view hierarchy.
EDIT :
With the example code you gave in edit 2, you call these lines :
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc]init];
[self.customAlert removeOkayButton:NO];
[self.customAlert removeCancelButton:NO];
}
but when you have just instantiated CustomAlertViewController, its 2 buttons are not yet created, so I suggest you add 2 properties hasOkButton and hasCancelButton and a new constructor to your custom class like this one :
- (instancetype) initWithOk:(BOOL)OkButton AndCancel:(BOOL) CancelButton
{
if(self = [super init])
{
hasOkButton = OkButton;
hasCancelButton = CancelButton;
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// At this time, the custom UI buttons will be created in the UI view hierarchy
[self removeOkayButton: hasOkButton];
[self removeOkayButton: hasCancelButton];
}
And in the caller you can use the following to display a custom alert View:
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [[CustomAlertViewController alloc] initWithOk:NO AndCancel:NO];
// ...
}
EDIT #2
I tried your solution in a real project, I made it work by using these lines int the caller :
- (IBAction)buttonAlert:(UIButton *)sender {
self.customAlert = [self.storyboard instantiateViewControllerWithIdentifier:#"customAlertView"];
self.customAlert.hasOK = NO;
self.customAlert.hasCancel = YES;
NSString *message = [NSString stringWithFormat:#"La tua offerta %# del 20%% è stata convertita in punti IoSi x10", self.promotionSelected];
[self.customAlert showCustomAlertInView:self.view withMessage:message];
isDeletingItem = YES;
}
In the CustomAlertViewController declare 2 visible properties hasOK and hasCancel in.h.
And modify your .m by adding method :
-(void)viewWillAppear:(BOOL)animated
{
[self removeOkayButton:self.hasOK];
[self removeCancelButton:self.hasCancel];
}
Be sure to modify your storyboard (if eligible) to have the "customAlertView" defined this way :
Don't forget also to bind your UIButton to the controller this can be a mistake too in your implementation :
Hope this will help you :)
I found on the web a tutorial to create custom alert view by using code, if you are interested you can go to this tutorial. I used it for my issue and it worked great! You have to fix a few things, because it uses deprecated command but it's easy to fix it.
If you are interested just take a look about this tutorial. I think you can integrate it in your app and after you can easily use for other stuff if it's necessary. I hope that my answer will help someone.
The problem is that when the button is clicked, it is not updating! it is not hiding or showing the objects like it's written in the code. What am I missing?
viewcontroller.h
#interface ViewController : UIViewController {
BOOL clicked1;
BOOL clicked2;
}
#property (strong, nonatomic) IBOutlet UIImageView *buttonbg1;
#property (strong, nonatomic) IBOutlet UIImageView *buttonbg11;
#property (strong, nonatomic) IBOutlet UIImageView *buttonbg111;
#property (strong, nonatomic) IBOutlet UIButton *exaa1;
#property (strong, nonatomic) IBOutlet UIButton *exab2;
- (IBAction)exaa1:(id)sender;
- (IBAction)exab2:(id)sender;
#end
viewcontroller.m
- (IBAction)exaa1:(id)sender {
clicked1 = YES;
}
- (IBAction)exab2:(id)sender {
clicked2 = YES;
}
- (void)example1 {
[_exaa1 setTitle:#"1111" forState:UIControlStateNormal];
[_exab2 setTitle:#"2222" forState:UIControlStateNormal];
if (clicked1) {
_buttonbg111.hidden = NO;
_buttonbg11.hidden = YES;
_buttonbg1.hidden = YES;
NSLog(#"1");
} else if(clicked2) {
_buttonbg11.hidden = NO;
_buttonbg1.hidden = YES;
_buttonbg111.hidden = YES;
NSLog(#"2");
}
}
*- (IBAction)exaa1:(id)sender {
clicked1 = YES;
[self example1];
}
- (IBAction)exab2:(id)sender {
clicked2 = YES;
[self example1];
}
- (void)example1 {
[_exaa1 setTitle:#"1111" forState:UIControlStateNormal];
[_exab2 setTitle:#"2222" forState:UIControlStateNormal];
if (clicked1) {
_buttonbg111.hidden = NO;
_buttonbg11.hidden = YES;
_buttonbg1.hidden = YES;
NSLog(#"1");
} else if(clicked2) {
_buttonbg11.hidden = NO;
_buttonbg1.hidden = YES;
_buttonbg111.hidden = YES;
NSLog(#"2");
}
}*
You just forget to call your method example1 in your both IBActions Method. YOu just write down [self example1] into both of the IBActions method. And you will get your exact output.
you forgot to call example1 method in both button IBAction methods
Please refer the following corrected code
- (IBAction)exaa1:(id)sender {
clicked1 = YES;
clicked2 = NO;
[self example1];
}
- (IBAction)exab2:(id)sender {
clicked2 = YES;
clicked1 = NO;
[self example1];
}
- (void)example1 {
[_exaa1 setTitle:#"1111" forState:UIControlStateNormal];
[_exab2 setTitle:#"2222" forState:UIControlStateNormal];
if (clicked1) {
_buttonbg111.hidden = NO;
_buttonbg11.hidden = YES;
_buttonbg1.hidden = YES;
NSLog(#"1");
} else if(clicked2) {
_buttonbg11.hidden = NO;
_buttonbg1.hidden = YES;
_buttonbg111.hidden = YES;
NSLog(#"2");
}
}
I've got a very weird problem with my iOS project.
I have a UIViewController with some labels and buttons and when user enters this view I programmatically build a gameboard (it's the minesweeper game).
What I wanted to do now is add a simple element (in my case a segmented control but i tried also with a button and doesn't work) at the bottom or at the beginning of the board.
When I add something from the Interface Builder I can see that in the storyboard but when I run the app puff, it's disappeared!
View contains only the "old" elements and the new one is not shown.
Yes I made a IBOutlet:
#property (weak, nonatomic) IBOutlet UISegmentedControl *clickTypeSegmentedControl;
And yes I checked if references of segemented control are ok.
I can't really understand what is wrong, if someone can help I'll be very grateful.
** EDIT: I added code of the ViewController, there are some other methods I left out because they only handle the game. I repeat: even if I add a simple button with no actions, it will not be shown.
#import "GameViewController.h"
#import "GameBoardModel.h"
#import "ScoreViewController.h"
#import <AVFoundation/AVFoundation.h>
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#interface GameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *timerLabel;
#property (weak, nonatomic) IBOutlet UILabel *bombsLabel;
#property (weak, nonatomic) IBOutlet UIButton *restartButton;
#property(nonatomic, strong) AVAudioPlayer *soundEffects;
#property (weak, nonatomic) IBOutlet UISegmentedControl *clickTypeSegmentedControl;
#end
#implementation GameViewController
#synthesize difficulty, timer, playerName, scoreToAdd, clickTypeSegmentedControl;
double secondsPassed=-1.0f;
int seconds=0;
int totalRowsCols=0, totalMines=0, heightWidth=0, clicKNumber=0;
static NSString * const IMAGE_NAME_FLAG = #"flag.png";
static NSString * const IMAGE_NAME_BOMB_X = #"bomb.png";
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *backButton =[[UIBarButtonItem alloc]initWithTitle:#"Menù" style:UIBarButtonItemStyleBordered target:self action:#selector(popAlertAction:)];
self.navigationItem.leftBarButtonItem=backButton;
clickTypeSegmentedControl.selectedSegmentIndex = 0;
rootController = (BombsSeekerViewController *)[self.navigationController.viewControllers objectAtIndex:0];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
playerName = [defaults objectForKey:#"NomeGiocatore"];
scoreToAdd = [[NSMutableDictionary alloc]init];
[self createGameBoard:difficulty];
[self newGame:nil];
}
-(void) newGame:(UIButton *)sender {
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
clicKNumber=0;
secondsPassed=0;
self.timerLabel.text = [self labelString:secondsPassed];
self.game = [[Game alloc] initWithWidth:totalRowsCols AndHeight:totalRowsCols AndMineCount:totalMines];
self.buttonArray = [[NSMutableArray alloc] init];
[self.restartButton addTarget:self action:#selector(newGame:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.restartButton];
[self.view addSubview:self.timerLabel];
[self.view addSubview:self.bombsLabel];
for(int i = 0; i < totalRowsCols; i++) {
for (int j = 0; j < totalRowsCols; j++) {
self.button = [[Tile alloc] initWithLocation: CGPointMake(j,i) andHW:heightWidth andBlock:self.game.board[j][i] andTag:(i*totalRowsCols+j)];
[self.buttonArray addObject:self.button];
[self.view addSubview:self.button];
[self.button addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchUpInside];
}
}
[self.timer invalidate];
}
- (void) createGameBoard:(int)diff{
switch (diff) {
case 1:
totalRowsCols = 6;
totalMines = 2;
heightWidth = 44;
break;
case 2:
totalRowsCols = 8;
totalMines = 16;
heightWidth = 35;
break;
case 3:
totalRowsCols = 10;
totalMines = 25;
heightWidth = 29;
break;
}
self.flagCount = totalMines;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
}
-(NSString *) labelString: (int) num {
if(num < 10) {
return [NSString stringWithFormat:#"00%i",num];
}
else if(self.timeCount.intValue < 100) {
return [NSString stringWithFormat:#"0%i",num];
}
else if(self.timeCount.intValue < 1000) {
return [NSString stringWithFormat:#"%i",num];
}
else
return #"---";
}
-(void) click:(Tile *)sender {
if(clicKNumber <1){
[self refreshLabel:self.timer];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(refreshLabel:)
userInfo:nil
repeats:YES];
clicKNumber++;
}
if(self.game.gameStatus == STATUS_LOST || self.game.gameStatus == STATUS_WON) return;
if (self.clickTypeSegmentedControl.selectedSegmentIndex == 0 && sender.block.marking == MARKING_BLANK) {
[self.game clickedAtColumn: sender.point.x AndRow: sender.point.y];
for(Tile *b in self.buttonArray) {
if(b.block.marking == MARKING_CLICKED) {
b.enabled = NO;
}
else if(b.block.marking == MARKING_BLANK) {
[b setTitle:#"" forState:UIControlStateNormal];
[b setImage:nil forState:UIControlStateNormal];
}
}
}
else if (self.clickTypeSegmentedControl.selectedSegmentIndex == 1){
if(sender.block.marking == MARKING_BLANK && self.flagCount > 0) {
sender.block.marking = MARKING_FLAGGED;
self.flagCount--;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
[sender setImage:[UIImage imageNamed:IMAGE_NAME_FLAG] forState:UIControlStateNormal];
}
else if(sender.block.marking == MARKING_FLAGGED) {
sender.block.marking = MARKING_BLANK;
self.flagCount++;
_bombsLabel.text = [NSString stringWithFormat:#"%d",self.flagCount];
[sender setImage:[UIImage imageNamed:#"tile.png"] forState:UIControlStateNormal];
}
}
if(self.game.gameStatus == STATUS_LOST) [self gameLost:sender];
else if(self.game.gameStatus == STATUS_WON) [self gameWon];
}
If this is what I think it is, you should not be doing this:
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
When the viewDidLoad is called, the newGame method is called, which removes al subviews from Superview. Including the ones added in Storyboard.
Make sure controller in storyboard is linked with the right controller class.
You call this method during -viewDidLoad:
-(void) newGame:(UIButton *)sender {
[self.view.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
//...
}
Thus, anything you put in your nib is getting removed after it loads.