I have a button that will segue to another View Controller. In shouldPerformSegueWithIdentifier I check the identifier and returns NO for this certain button after calling my own method nextClicked.
In nextClicked I do a HTTP Request and check some stuff, and then if everything is OK I do
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:self];
});
The problem is that I get no animation now... The segue is of type modal. If I return YES in shouldPerformSegueWithIdentifier and don't to the segue programmatically later, the animation appears and everything is as it should.
You are misusing shouldPerformSegueWithIdentifier. If you want to do something special in response to the button click, use action-target and not a segue connected to the button.
I created a new project with your idea and I've got animation.
This is the action connected through IB with the next viewController and with identifier: #"getstartednext"
- (IBAction)go:(id)sender
{
}
Same code you have except sender is nil
- (void) nextClicked
{
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"getstartednext" sender:nil];
});
}
if sender != nil, (IBAction go:) then I'm calling nextClicked because returning NO
else the code is doing the segue because returning YES
- (BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"getstartednext"] && sender != nil)
{
[self nextClicked];
return NO;
}
return YES;
}
Works like a charm.
Related
So i am showing a model controller on top of a view controller. And i have texts in the model controller, but somehow the texts are not visible. I tried everything but somehow labels are not visible. But of you stay on the page for like 30 -40 sec the text shows up. Also this model controller is called from main view controller after a successful service(REST) call. If i call the model without making the service call then labels are visible in simulator/iPad both. But if i call it after service call inside success block then labels are not visible. I tried adding the text programmatically but still same issue. I tried debugging using Color blended layers, but the label is not at all visible in the view somehow. :(
[self.serviceManager getCustDetails:account successBlock:^(NSDictionary * successDict) {
[self hideLoadingAnimation];
NSDictionary *custData = [[successDict objectForKey:#"txnData"] objectForKey:#"custData"];
self.showCurrYear = [iraContribData objectForKey:#"showCurrYear"];
if ([self.showCurrYear isEqual: #"true"]){
[self performSegueWithIdentifier:#"CSegue" sender:self];
}
} failureBlock:^(NSDictionary * failureDict) {
[self hideLoadingAnimation];
NSLog(#"Failiure Dict %#",failureDict);
}];
And this prepareForSegue method, -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"CSegue"]) {
CustViewController *cVC = segue.destinationViewController;
cVC.delegate = self;
[cVC setModalPresentationStyle:UIModalPresentationFormSheet];
cVC.preferredContentSize = CGSizeMake(800,750);
}
}
Below is my screen in storyboard, but in simulator the label is not visible, only continue and close button is visible.
Please help!, any suggestions are most welcome. Thanks!
It is possible that the delay is due to a user interface update not made on the main thread.
Try to make sure that your code is executed on the main thread using dispatch_async like this :
[self.serviceManager getCustDetails:account successBlock:^(NSDictionary * successDict) {
dispatch_async(dispatch_get_main_queue(), ^{
[self hideLoadingAnimation];
NSDictionary *custData = [[successDict objectForKey:#"txnData"] objectForKey:#"custData"];
self.showCurrYear = [iraContribData objectForKey:#"showCurrYear"];
if ([self.showCurrYear isEqualToString:#"true"]){
[self performSegueWithIdentifier:#"CSegue" sender:self];
}
});
} failureBlock:^(NSDictionary * failureDict) {
dispatch_async(dispatch_get_main_queue(), ^{
[self hideLoadingAnimation];
NSLog(#"Failiure Dict %#",failureDict);
});
}];
I have two view controllers: CropImageViewController and ImageCropperViewController
In CropImageViewController I have this method:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"prepareForSegue called");
if([segue.identifier isEqualToString:#"goBack"])
{
NSLog(#"processedText = %#",self.processedText);
[segue.destinationViewController setProcessedText:self.processedText];
}
}
Then, in ImageCropperViewController, I have this:
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"view will appear called");
//self.processedImageLabel.text = self.processedText;
NSLog(#"processedText = %#",self.processedText);
NSLog(#"testLabel: %#",self.testField.text);
}
This is the console output. For some reason, "processedText" is always NULL no matter what.
2014-05-23 16:51:43.488 ImageCropper[9294:60b] prepareForSegue called
2014-05-23 16:51:43.490 ImageCropper[9294:60b] processedText = E33
===..., ____
2014-05-23 16:51:43.493 ImageCropper[9294:60b] view will appear called
2014-05-23 16:51:43.494 ImageCropper[9294:60b] processedText = (null)
I see your segue "goBack". Are you come back after pushed CropImageViewController from ImageCropperViewController?
So in this case you shouldn't use a segue. You should write an IBAction for your button (or i don't know what you have to come back) and when you press it do:
[self popViewControllerAnimated:YES];
but before this, you should call the delegate to pass the new value:
[_delegate changeProcessedText:self.processedText];
Obviously i assume that you know how implement a delegation pattern.
Another way could be use KVO, so observing from the first viewController, the processedText.text value in the second viewController.
I have an app having 7 screen. On the screen 7 i have a button that does valiation and submits data and then it jumps to screen 1 using modal segue.
But ,I only want to move screen1 if the validation succeeds or else i dont want to move to screen1.
Currently its moving to screen 1 independent of validation.
button click code is as below
- (IBAction)submitButtonActionForDemo:(id)sender
{
if (![JLTValidator validateFields:#[_authRepresentative, _acceptDeclarationStatement,_homeTeamRepName,_homeTeamRepPosition,_awayTeamRepName,_awayTeamRepPosition]])
{
// how to disable a modal segue here.
return;
}
}
JLTValidator is my validating class here.
Pls suggest/help. Thanks in adv.
If you want to only allow the segue some times, you need to "name" the segue in InterfaceBuilder, then implement this routine:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if ([identifier isEqualToString:#"your segue name"]) {
return false;
}
return true;
}
Sorry if the title isn't very clear, but hopefully I can elaborate here.
I have a ViewController MatchLineupViewController, which displays 22 buttons to represent rugby players on a team. When the user taps any of these buttons, a modal segue is called programmatically in the following method:
- (IBAction) showSquadSelector:(UIButton *)sender {
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
}
The modal ViewController which is then displayed is called SquadSelectViewController. It passes back a selected player object to the MatchLineupViewController, which is acting as a delegate. This works perfectly.
However, I want to assign the profile_picture attribute of the returned object to the UIButton that sent the segue in the first place.
EDIT - The returned object is an NSDictionary as shown in the following code:
- (void) selectPlayer:(NSDictionary *)player forButton:(UIButton *)sender {
[sender.imageView setImage:[UIImage imageWithContentsOfFile:[player objectForKey:#"profile_picture"]]];
}
How would I go about doing this? If you require any further code to understand what I am asking, I can provide it.
Many thanks,
Chris
EDIT -
- (IBAction) showSquadSelector:(UIButton *)sender {
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SeguePopupSquad"]) {
SquadSelectViewController *ssvc = (SquadSelectViewController *) segue.destinationViewController;
ssvc.myDelegate = self;
ssvc.senderButton = sender;
}
}
- (void) selectPlayer:(NSDictionary *)player forButton:(UIButton *)sender {
[sender.imageView setImage:[UIImage imageWithContentsOfFile:[player objectForKey:#"profile_picture"]]];
NSLog(#"%#", [player description]);
NSLog(#"%#", [sender description]);
}
You can forward the sender of your showSquadSelector: method to the segue, like this:
[self performSegueWithIdentifier:#"SeguePopupSquad" sender:sender];
The sender of the segue would be the button that triggered the segue, so the code triggered from the segue would know what button has triggered it: your prepareForSegue: would have the correct UIButton. You can now add it to the returned dictionary at a predetermined key (say, #"senderButton") and examine it upon the return from the segue.
I am doing a custom Segue on Storyboard and I have a button that contains this code:
[self performSegueWithIdentifier:#"line3" sender:sender];
By clicking on the button it works well. The problem I am running into that this code only works inside a button function not inside a void function. I tried clicking on the button and it works well. When I paste it inside just a void function it gives me an error complaining about the sender. I tried changing it to void but nothing happens. Can you give me some insight on to fix this issue. I am checking a UserDefault and it matches what I am looking for then I want to to perform this code: [self performSegueWithIdentifier:#"line3" sender:sender];
-(IBAction)LoginAttemp:(id)sender{
[self performSegueWithIdentifier:#"line3" sender:sender];
}
-(void) LoginFailed{
[self performSegueWithIdentifier:#"line3" sender:sender];
}
Error I Get:
Use of undeclared identifier 'sender'
Any insight?
change
[self performSegueWithIdentifier:#"line3" sender:sender];
to
[self performSegueWithIdentifier:#"line3" sender:Nil];
the sender is:
The object that you want to use to initiate the segue. This object is
made available for informational purposes during the actual segue.
void isn't the issue. The issue is that sender is not a reserved word. It's one of the parameters to your IBAction:
-(IBAction)LoginAttemp:(id)sender{
See? Right there at the end. That's Objective-C equivalent of IBAction LoginAttemp(id sender)
If you don't have a sender, you can pass nil or self. Using self would be preferred.
-(void) LoginFailed{
[self performSegueWithIdentifier:#"line3" sender:self];
}