在执行代码之前等待用户关闭模态视图(Swift 2.0)
Posted
技术标签:
【中文标题】在执行代码之前等待用户关闭模态视图(Swift 2.0)【英文标题】:Wait for user to dismiss Modal View before executing code (Swift 2.0) 【发布时间】:2016-03-10 22:27:43 【问题描述】:我正在构建一个应用程序,如果用户在用户点击“拒绝”后立即使用以模式显示的模式访问其当前位置,他们会要求用户选择一个位置。此模式将信息显示为 TableView,一旦用户选择一行,模式就会消失。我将此选择保存在一个名为selectedStop
的变量中。 我希望应用暂停,直到用户选择一个位置,然后一旦用户选择一个位置,应用就会继续并执行 setUpMap() 函数。我尝试在 setUpMap() 中使用无限 while
循环,并在用户选择一行后立即使用布尔值打破它,但 while 循环甚至在模态弹出之前执行。
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】:使用Int
变量传递信息将不起作用,因为它是一个值 类型,每次传递时都会被复制。这意味着当您更改 didSelectRowAtIndexPath
方法中的 selectedStop
时,ViewController
中的原始 selectedStop
仍将为 nil 或其他任何内容。
然后,回答你的问题。有几种方法可以解决这个问题。
您可以像这样将block
(而不是int
)传递给ModalViewController
:
var stopSelectedHandler: (Int) -> Void = selectedStop in
// Do something here.
// setUpMap()
您将在dismissViewControllerAnimated
的completion
处理程序中调用此块。
您可以使用通知。
// 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.
你也可以使用 KVO、delegate 等。使用适合你的任何东西。
像这样放置块:
class ViewController: UIViewController
var stopSelectedHandler: (Int) -> Void = selectedStop in
// Do something here.
// setUpMap()
....
【讨论】:
感谢您的帮助。如何将block
传递给 MVC?我要destViewController.selectedStop = stopSelectedHandler
吗?
@Ivan 是的,您还必须在 destViewController 中声明一个块变量。 var stopSelectedHandler: ((Int) -> Void)?
做destViewController.stopSelectedHandler = stopSelectedHandler
我应该把var stopSelectedHandler: (Int) -> Void = selectedStop in ...
放在哪里?那是在destViewController.selectedStop = stopSelectedHandler
之前吗?我为造成的混乱道歉,我还在学习 Swift。
@Ivan 可以放在前面。您还可以将块视为属性。检查我的答案。以上是关于在执行代码之前等待用户关闭模态视图(Swift 2.0)的主要内容,如果未能解决你的问题,请参考以下文章