I'm working on the IOS Programming: Big Nerd Ranch Guide Chapter 5 Silver Challenge and am wracking my brain trying to hook up the UISegmentedControl's change event.
Controller.m's initializer contains:
[segmentedControl addTarget:self
action:#selector(onChangeSegment:)
forControlEvents:UIControlEventValueChanged];
Controller.m also contains:
- (void) onChangeSegment:(id)sender
{
NSLog(#"Phew made it!");
}
Controller.h contains:
#interface
//...
- (void) onChangeSegment:(id)sender;
#end
All appears to be in place, however when the active segment is changed from the UI, onChangeSegment is never messaged. This is the case with either the simulator or my iPhone4S (IOS7 and XCode 5).
Any help or direction is appreciated. Please let me know if I can supply more details.
Please do a
NSLog(#"segmentedControl: %#", segmentedControl);
before your target action adding. Its possible you're trying to addTarget: to a nil object. If you're doing this via Interface Builder, the addTarget should be done in the -viewDidLoad: method.
What I did in a sample app was:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.segmentedControl addTarget:self action:#selector(change:) forControlEvents:UIControlEventValueChanged];
}
-(void)change:(UISegmentedControl *)control{
NSLog(#"changed!");
}
The Segmented Control was created using IB and linked to the view controller's header.
You said:
Controller.m's initializer contains:
In initializer you don't have IBOutlets from XIB so segmentedControl == nil at that time and method call does nothing. Views are usually configured in -viewDidLoad method where IBOutlets are guaranteed to be loaded from xib. So simply move
[segmentedControl addTarget:self
action:#selector(onChangeSegment:)
forControlEvents:UIControlEventValueChanged];
to -viewDidLoad method. Other things seem to be ok.
Related
The way I went about coding my app was to load my views through methods in my ViewController.m file.'s implementation. After loading views my app progressed through menus and displays by button actions and updated my setting the self.view to different displays generated by my methods. The problem with this is my memory consumption. Each time a button is pressed my methods that display the next "view" becomes a child and so on. This chews up memory like crazy and I don't want to recode everything (I didn't use storyboard I used only coded). I tried creating a method in an infinite loop that switched views but it wouldn't update self.view. I need a way of switching views using only code (displaying my views with storyboard isn't possible, too complicated to align).
example code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
...global vars...
-(void)viewDidLoad {
[super viewDidLoad];
...setup...
[self Load_Main_Menu];
}
-(void)Load_Main_Menu {
...setup UIView display...
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
[Button addTarget:self action:#selector(PlayButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.view=display;
}
-(void)PlayBt:(UIButton*)sender{
[self load_Other_Menus];
}
All navigation and UI is handled as such.
Any ideas for improving memory management and navigation?
try this
-(void)viewDidLoad {
[super viewDidLoad];
...setup...
[self setupButton];
[self displayView];
}
-(void)setupButton {
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
[Button addTarget:self action:#selector(displayView) forControlEvents:UIControlEventTouchUpInside];
..add button to view
}
-(void)displayView {
...setup UIView display...
self.view=display;
}
I have a UIButton. I bound a target as follows.
[button addTarget:self action:#selector(myFunction)
forControlEvents:UIControlEventTouchUpInside];
When i click my Button multiple times quickly it invoke the target function multiple times.
On Tapping button i present a new View controller.
when i click 3 times quickly then my new view controller is shown 3 times.
This is something stupid. Whats the point of triggering the function again once the View has been shifted to a new View controller. Why the Hell Apple do such stupid things ?
Any Help please?
First of all its not apple bugs. It should be handle manually. So follow these step
First make your global instance of your button then do this
.h file
#property (weak, nonatomic) IBOutlet UIButton *btn;
.m file
- (IBAction)myFunction:(id)sender
{
self.btn.userInteractionEnabled = NO;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.btn.userInteractionEnabled = YES;
}
Take one global bool flag like "isItDone" or it declare in singleton class.
in "myFunction" set it as false
which View controller you push on that function in that class's "ViewDidAppear" method set as true.
it will help you.
I have same problem and it is good solution for that to manage it using one global variable.
I think this will help you.
Change your calling function like this
- (IBAction)myFunction:(id)sender
{
UIButton *button = (UIButton*)sender;
button.userInteractionEnabled = NO;
}
and call your function like this
[button addTarget:self action:#selector(myFunction:)
forControlEvents:UIControlEventTouchUpInside];
if you want to store the selection incase you came back to the view controller then only you need to keep a boolean flag to store if its clicked once or not.
Set the IBOutlet to your button, in the viewWillAppear method write,
button.userInteractionEnabled = YES;
and when you click on the button set,
button.userInteractionEnabled = NO;
I am subclassing an UIButton which is going to be present in all of my app's ViewControllers, kinda Navigation Button. I would like just to put it to my VC and apply custom class, without any code in ViewController itself. So, the questions:
1. is it possible?
2. I am using this code now in my UIButton custom class. What is wrong?:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addTarget:self action:#selector(didTouchButton) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)didTouchButton {
NSLog(#"YEAH, it works, baby!");
}
UPD: seems that even initWithFrame method is not being called at all.
Loading from the nib I think.The initWithFrame method doesn't work if not called programatically.
Try -awakeFromNib Method
See this question
I have a UITableView that i would like to hide until the user taps the button searchButtonTapped. (I'm also using this button as an IBAction.)
Originally i'm hiding the table view as you see in the viewDidLoad, and i wanna show it after the button was tapped, but it does not shown up after i tap the search button. Do i missed something? For me, it seems it should be work properly, after the button was tapped i refresh the table view.
my .h file
#property (weak, nonatomic) IBOutlet UIButton *searchButtonTapped;
- (IBAction)searchButton:(id)sender;
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.hidden = YES;
}
- (void)buttonTapped:(id)sender {
if (sender == self.searchButtonTapped) {
self.tableView.hidden = NO;
[self.tableView reloadData];
}
}
- (IBAction)searchButton:(id)sender {
[self searchSetup];
}
It's impossible to tell from the little bit of code that you posted. Add NSLog statements in your buttonTapped method that show entering the method, entering the if statement, the value of searchButtonTapped, and the value of self.tableView.
Then you can tell if the method is getting called, if the if statement is evaluating as true, and if the table view is non-nil. One of those things is likely to be the cause of your problem.
I'm guessing that the if statement is wrong. what type is the property self.searchButtonTapped? Post the code that declares that property.
Based on the name I would guess that searchButtonTapped is a boolean?
you have declared only one IBAction, which is for the method searchButton.
This method call the searchSetup´s method. What is the purpose of it?
- (IBAction)searchButton:(id)sender {
[self searchSetup];
}
So you must have another IBAction for buttonTapped method witch is currently a "void" method and not a IBAction. Or you make that connection from the storyBoard, or you must declare it programaticly like:
[self.searchButtonTapped addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]
When using drawRect for a custom UIButton subclass, it never seems to get called to draw the button when highlighted. Do I need to call setNeedsDisplay for my button in my touch events?
I found an easy solution.
Just add the following method to your UIButton subclass:
-(void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
[self setNeedsDisplay];
}
That's it!
As far as i can tell there is no straight forward way to subclass UIButton.
UIButton is not the actual class type that is returned by the initializers. UIButton is kind of a front for a series of private classes.
Say you had:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
NSLog(#"myButton type: %#", [myButton description]);
You will find the type returned in the log to be "UIRoundedRectButton". The problem with that is you would need to have extended "UIRoundedRectButton". That is not possible as it is a private class which is only ever returned to UIButton.
On top of that "UIRoundedRectButton" is not the only possible returned class all of which are private.
In other words UIButton was built in manner that is not suited to be extended.
I had the same problem and satisfying success with the following added to my UIButton subclass
- (void)awakeFromNib {
[self addTarget:self action:#selector(redraw) forControlEvents:UIControlEventAllEvents];
}
- (void)redraw {
[self setNeedsDisplay];
[self performSelector:#selector(setNeedsDisplay) withObject:self afterDelay:0.15];
}