问题
I try to build an rss reader. On the "adding feed" page, if I tap the "add" button, I hope to check if the feed is successfully added. If it is added, then trigger the unwind segue, and back to the main page. If it is not added, stay in the current page.
I know I can build an IBAction on the "add" button, and check if the feed is added. However there are two requirements I need to meet in order to add a feed.
First, after I parse the url, I need to know if the parse results can generate a feed. To parse the url, I need to use the method defined in the mainViewController.
Second, I need to check if the feed already exists. If this feed already exists, don't add it. To check this, I need to get the feed data from mainViewController.
Currently I use prepareForSegue to pass the data from main viewController to this view. But for the conditional unwind segue, I don't know how to pass the data and check if the feed already exists. Because prepareForSegue is used only when the segue is going to be triggered. If the segue is not triggered, I can't check the condition.
Besides through segue, is there any other ways to pass data from other view?
I don't know objective-C, so it would be better if you can give me some solutions in swift. :)
回答1:
Like Schemetrical said, using a delegate is an easy way to access the methods in your MainViewController.
Since you tagged this as Swift, I'll also give you a small example of a delegate in Swift.
First you create a protocol:
protocol NameOfDelegate: class { // ":class" isn't mandatory, but it is when you want to set the delegate property to weak
func someFunction() -> String // this function has to be implemented in your MainViewController so it can access the properties and other methods in there
}
In your MainViewController you have to add:
class MainViewController: UIViewController, NameOfDelegate {
// your code
@IBAction func button(sender: UIButton) {
performSegueWithIdentifier("toOtherViewSegue", sender: self)
}
fun someFunction() -> String {
// access the other methods and return it
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toOtherViewSegue" {
let destination = segue.destinationViewController as! OtherViewController
destination.delegate = self
}
}
}
And the last step, you'll have to add a property of the delegate, so you can "talk" to it. Personally I imagine this property to be a gate of some sort, between the two view controllers so they can talk to each other.
class OtherViewController: UIViewController {
weak var delegate: NameOfDelegate?
@IBAction func button(sender: UIButton) {
if delegate != nil {
let someString = delegate.someFunction()
}
}
}
I assumed you used a segue to access your other ViewController since you mentioned it in your post. This way, you can just "talk" to your MainViewController.
EDIT:
As for the unwind. This also can be done through a segue.
- add:
@IBAction func unwindToConfigMenu(sender: UIStoryboardSegue) { }
to your MainViewController. - In your storyboard there are 3 icons at the top of your
OtherViewController
. Click on the round yellow with a square inside to make sure the ViewController is selected and not some elements inside. - Control drag (or right mouse drag) from the same round yellow with a square inside to the most right red square icon. Doing so pops up a menu where you can select the unwind segue.
- Click on the new segue you just created. Give it an identifier like "backToMain"
- Add something similar as the code below to
OtherViewController
It appears i can't post any code anymore? :o will add it later.
回答2:
You can always use delegates.
Set up a delegate in your add feed page and get mainViewController
to conform to the delegate. Add a delegate method (- (BOOL)canGenerateFeed:(NSURL *)url
) and a delegate property (@property (weak, nonatomic) id <AddFeedControllerDelegate> delegate
).
When your add feed page calls [self.delegate canGenerateFeed:url]
and your mainViewController
conforms to the delegate, the method in mainViewController
is called (that should reply BOOL as stated in the method declaration). Then you can reply YES or NO accordingly, which will be sent back through to the add feed page.
回答3:
- (UIViewController*)viewControllerForStoryboardName:(NSString*)storyboardName class:(id)class
{
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
NSString* className = nil;
if ([class isKindOfClass:[NSString class]])
className = [NSString stringWithFormat:@"%@", class];
else
className = [NSString stringWithFormat:@"%s", class_getName([class class])];
UIViewController* viewController = [storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:@"%@", className]];
return viewController;
}
// get the view controller
ViewController* viewController = (ViewController*)[self viewControllerForStoryboardName:@"MyStoryboard" class:[OtherViewController class]];
// Pass data here
viewController.data = myData;
// or you can push it
[self.navigationController pushViewController:viewController animated:YES];
来源:https://stackoverflow.com/questions/29586281/how-to-pass-data-in-conditional-unwind-segue