在执行代码之前等待用户关闭Modal View(Swift 2.0)

时间:2016-03-10 22:27:44

标签: swift tableview segue modalviewcontroller

我正构建一个应用程序,要求用户选择一个位置,如果他们不允许在用户点击后立即使用模式呈现模式来访问其当前位置'拒绝&#39 ;.此模式具有显示为TableView的信息,并且一旦用户选择行,模态就会解除。我将此选择保存在名为selectedStop的变量中。 我希望应用暂停,直到用户选择一个位置,然后一旦用户选择一个位置,应用程序就会继续,并且setUpMap()函数会执行。我尝试在setUpMap()中使用无限while循环,并在用户选择一行时使用布尔值来跳出它,但是在模态甚至弹出之前执行while循环。 / p>

ViewController.swift

class ViewController: UIViewController {
    var selectedStop: Int!

    override func viewDidLoad() {
        super.viewDidLoad()
        // If we don't have access to the user's current location, request for it
        if (CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedWhenInUse) {
            locationManager.requestWhenInUseAuthorization()
        }
    }

    func setUpMap() {
        // do stuff with var selectedStop
    }

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .Denied:
            // if user denies access, display modal
            self.performSegueWithIdentifier("NotifyModally", sender: self)
            setUpMap() // need this func to execute AFTER location is selected
            break

        case .AuthorizedWhenInUse:
            setUpMap()
            break

        default:
            break
        }
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if (segue.identifier == "NotifyModally") {
            let destViewController:ModalViewController = segue.destinationViewController as! ModalViewController
            // send selectedStop var to ModalViewController
            destViewController.selectedStop = selectedStop
        }
    }
}

ModalViewController.swift

class ModalViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var tableView: UITableView!

    var busStops = ["Stop 1", "Stop 2", "Stop 3"]
    var selectedStop: Int!

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return busStops.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel!.text = busStops[indexPath.row]
        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedStop = indexPath.row
        dismissViewControllerAnimated(true, completion: nil)
    }
}

1 个答案:

答案 0 :(得分:1)

使用Int变量传递信息将无法正常工作,因为它是类型,每次传递它时都会被复制。这意味着当您更改selectedStop方法中的didSelectRowAtIndexPath时,selectedStop内的原始ViewController仍然是零或无论如何。

然后,回答你的问题。有几种方法可以解决这个问题。

  1. 您可以将block(而不是int)传递给ModalViewController,如下所示:

    var stopSelectedHandler: (Int) -> Void = { selectedStop in
        // Do something here.
        // setUpMap()
    }
    
  2. 您将在completion的{​​{1}}处理程序中调用此块。

    1. 您可以使用通知。

      dismissViewControllerAnimated
    2. 您也可以使用KVO,代表等。使用适合您的任何内容。

      像这样放置块:

      // Do this inside `ViewController`.
      NSNotificationCenter.defaultCenter().addObserver(self, selector: "setupMap:", name: "UserDidSelectStop", object: nil)
      
      // And then post the notification inside `didSelectRowAtIndexPath`
      NSNotificationCenter.defaultCenter().postNotificationName("UserDidSelectStop", object: nil, userInfo: ["selectedStop": 2])
      
      // Change your setupMap to this
      func setupMap(notification: NSNotification) {
          guard let selectedStop = notification.userInfo?["selectedStop"] as? Int else { return }
          // Now you can use selectedStop.
      }