Programmatically tap UIButton not working - ios

I have an iPad app using XCode 4.6, Storyboards, iOS 6.2. I looked at SO and Google, but nothing about when to send the message to the button.
I am trying to save some data to CoreData when the user leaves a "scene" but it's not working. Here is the code:
-(void) viewWillDisappear:(BOOL)animated {
[bSavePreferences sendActionsForControlEvents:UIControlEventTouchUpInside];
}
-bSavePreferences is in the same class as viewWillDisappear, but it never gets called. Why?
UPDATE: I should have mentioned that I am using a UITabBarController to control which page is selected.

A few things...
You shouldn't be invoking an action this way. You should just call the IBAction method directly to do the saving.
You need to call [super viewWillDisappear:animated] at some point when implementing viewWillDisappear.
As for the root problem, viewWillDisappear is called in response to the view being removed from the view hierarchy. It's possible that the UIButton would no longer be able to receive events at this point. I encourage you to look at the documentation.

There are multiple methods:
One way is to add a target action to your button:
[myButton addTarget:self
action:#selector(myAction) forControlEvents:UIControlEventTouchUpInside];
The second option is to use IBActions:
- (IBAction)ButtonPressed { NSLog#"press"; }
Make sure you wire your outlets correctly!

Related

WKInterface button doesn't change title

I'm trying to change the title of a button after I call back from a notification but it doesn't respond at all. I checked it's not nil and checked the text Im' assigning and all is good. I made the property type strong instead of weak but no success.
- (void) setButtonTitleFromSelectedSearchResult:(NSNotification *)notif
{
[self popController];
self.sourceMapItem = [[notif userInfo] valueForKey:#"SelectedResult"];
NSLog(#"The Selected Result is: %#", self.sourceMapItem.name);
//Testing
NSLog(#"%#", self.fromButton); // check it's not nil
[self.fromButton setTitle:self.sourceMapItem.name];
}
With WatchKit, if a user interface element isn't currently visible, it cannot be updated. So, if you've presented another interface controller "on top", you can't update any of the presenting controller's interface elements until you've dismissed the presented controller. At that point, you can safely update the presenting controller in its willActivate method.
SushiGrass' method of passing blocks is certainly one valid approach. In my testing, however, I ended up having to manage multiple blocks, and many of the subsequent blocks reversed what earlier queued blocks had accomplished (for example, first changing a label's text to "foo", then "bar", then "foo" again. While this can work, it isn't optimal.
I'd suggest that anyone who is working on a WatchKit app takes a moment to consider how they want to account for off-screen (i.e. not-currently-visible) interface elements. willActivate is your friend, and coming up with a way to manage updates in that method is worthwhile if you're moving from controller to controller.
For what it's worth, I've encapsulated a lot of this logic in a JBInterfaceController subclass that handles a lot of this for you. By using this as a base class for your own interface controller, you can simply update your elements in the added didUpdateInterface method. Unfortunately, I haven't yet had the time to write proper documentation, but the header files and sample project should get you going: https://github.com/mikeswanson/JBInterfaceController
I'm using latest XCode 6.3 and below code working with me.
self.testBtn is bind with Storyboard and its WKInterfaceButton
I also have attached screenshot with affected result.
I'm setting initial text in - (void)willActivate
- (void)willActivate {
[super willActivate];
[self.testBtn setTitle:#"Test"];
[self performSelector:#selector(justDelayed) withObject:nil afterDelay:5.0]
}
-(void)justDelayed
{
[self.testBtn setTitle:#"Testing completed...!!"];
}
If you're using an IBOutlet for the property fromButton be sure that is connected to WKInteface on the storyboard, like below:
I solved this kind of issue by creating a model object that has a property that is a block of type () -> (Void) (in swift). I create the model object, set the action in the block that I'd like the pushing WKInterfaceController to do on completion, and finally pass that model object in the context to the pushed WKInterfaceController. The pushed WKInterfaceController holds a reference to the model object as a property and calls it's completion block when it's done with whatever it needs to do and after func popController().
This worked for me for patterns like what you are describing along with removing rows on detail controller deletion, network calls, location fetches and other tasks.
You can see what I'm talking about here: https://gist.github.com/jacobvanorder/9bf5ada8a7ce93317170

Trigger button inside UITextView Event

Im trying to trigger a button event inside the UITextView on change event
I tried
-(IBAction)myTextfield:(id)sender
{
[self.myButton sendActionsForControlEvents:UIControlEventTouchUpInside];
}
when NSLog(#""); the event it will show up in the debugger but it does'nt do anything with the sendAction
Does someone know what im missing or doing wrong
Thank you very much.
Indeed i created a -(void)myMethod; and put my code in the this method
-(IBAction)myTextfield:(id)sender
{
[self myMethod];
}
You must register the action to your button. see the home documents:
UIControl implements this method to send all action messages associated with controlEvents, repeatedly invoking sendAction:to:forEvent: in the process. The list of targets and actions it looks up is constructed from prior invocations of addTarget:action:forControlEvents:.
so you use the addTarget:action:forControlEvents:. to your button ,so it works.

Can I connect xib object to any viewController?

I know it is possible to connect an object in a XiB file (i.e button) and connect it to any viewController. I am also able to go to that viewController and programmatically set properties to that object(everything autocompletes fine, it recognizes the object properties) However, when I run the app, the button is unchanged, what gives?
Is there something I'm missing? Is there an additional step that I need to do when using a ViewController that is not the .m file related to the XIB?
Here's part of the code... I don't get any errors!
user.default_sales_rep_id = 2;
if (user.default_sales_rep_id > 0) {
buttonMask.backgroundColor = [UIColor blackColor];
}
You are most likely setting the properties on the button too early. Since you don't specify in your question where this code is located, it's hard to say but I'd guess if you put your code in awakeFromNib it would work.
- (void)awakeFromNib {
[super awakeFromNib];
//code here
}
Any changes to your view that differ from your XIB should be done in this method as it is called after the view is set up from the XIB.
Are you certain you are calling [[UIButton alloc] init] before you attempt manipulating it? I assume you have the button already as an IBOutlet, but if I recall, if you wish to make custom changes to the button, you must still do this.

Popup creation in IOS/iPad

I have created a popup and in that there is a list of content are displaying in a table view. Now when I click into any row of the tableview, it should call a method, which is available in the parent view not in the popup view. If I use any button in that popup then after selecting a row if I click into that button then it works. The button action is mention in parent view in this way.
[controller.gotoButton addTarget:self action:#selector(clickMe:) forControlEvents:UIControlEventTouchUpInside];
So how to call a method when clicking into a table rows?
Here you can find a pretty good description of delegates.
What you would like to do, can be solved with a protocol/delegate. You should create the protocol in the Popup view's header file, and the implementation in the *.m class. Your parent view should implement the protocol, and don't forget the connection line, the myPopupObject.delegate = self; + the implementation of the protocol's method.
I suggest to use the
if ([delegate respondsToSelector:#selector(myMethod:)]) {
//call the selector
}
verification in the Popup view class, because if the protocol's method is optional, and you hadn't implemented it in the parent class, your app will crash (you won't receive any error/warning message from the compiler, because it was an optional method).
in rowDidSelect,
create a object for the parentview
eg:
parentClass *pc=[parentClass alloc]init];
[pc method:];

How to show the text of an UITextField in an UILabel?

I am building an interface, where I can add events like in a calendar.
In the AddAEventViewController I have Buttons to set the starttime, duration and recurrence.
Every time you press a button a viewcontroller comes up with a UIDatePicker, where you can set your time. The picked component is than displayed in a UITextField. Now when I press the Done-Button, it dismisses the ModalViewController and I am back to my AddAEventViewController. Next to the Durationbutton e.g. is a UILabel, where I want to show now the just picked and in the textfield shown duration.
How do I get access to the AddEventViewController out of an other ViewController? I tried to alloc and init a new one there, but it didnt work!
- (IBAction)pressedDoneButton:(id)sender {
_mainAddWishViewController.labelDuration.text=textFieldDuration.text;
[self dismissModalViewControllerAnimated:YES];
}
Can someone help me please!
Thank you Jules
There are several ways you can do this, all of them documented here. Reading and understanding them will help you a lot in iOS software development.
There are many ways to achieve this. Here is one that is fairly straightforward.
In the "child" viewController, add a delegate property and set it to the parent view controller.
Then in your Done button handler, do something like:
[self.delegate performSelector:#selector(didComplete) withObject:self]
In the parent view controller, define a method as follows:
- (void) didComplete: (YourSubViewControllerClass *) sender
{
self.labelDuration.text = sender.textFieldDuration.text
}
Basically, this implements an informal protocol whereby the subViewController informs the main view controller that it is finished and input values are available.
Note that if you cancel out of the subViewController, don't send the didComplete message.

Resources