在取消容器视图中的childviewController显示的模态视图时,我遇到了一些问题。我有一个UINavigationController as rootViewController (MainNavigationController),并呈现了一个来自selectedSegmentIndex 1 (secondViewController)的childViewControllers的模态。该模型显示得很好,但当我拒绝将该模型返回到secondViewController(HomeController的一个子类)时,它会将我返回到selectedIndex 0,而不是从selectedIndex 1 childViewController返回。我希望这个模式能够拒绝用户并将其返回给childViewController,它是从( secondViewController)中呈现的,而不是返回到selectedIndex 0。提前感谢!
// NavigationConroller作为rootViewController
class MainNavigationController: UINavigationController {
var segmentedController: UISegmentedControl!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let vc1 = TravelersFeedVC()
let vc2 = ProfileVC()
if isLoggedIn() {
// assume user is logged in
let homeController = HomeController()
viewControllers = [homeController]
homeController.firstViewController = vc1
homeController.secondViewController = vc2
} else {
perform(#selector(showLoginController), with: nil, afterDelay: 0.01)
}
}
fileprivate func isLoggedIn() -> Bool {
return UserDefaults.standard.isLoggedIn()
}
func showLoginController() {
let loginController = LoginController()
present(loginController, animated: true, completion: {
// perhaps do something here later
})
}
}// HomeController作为parentViewController
class HomeController: UIViewController, FBSDKLoginButtonDelegate {
// child view controllers to put inside content view
var firstViewController: TravelersFeedVC?
var secondViewController: ProfileVC?
private var activeViewController: UIViewController? {
didSet {
removeInactiveViewController(inactiveViewController: oldValue)
updateActiveViewController()
}
}
private func removeInactiveViewController(inactiveViewController: UIViewController?) {
if let inActiveVC = inactiveViewController {
// call before removing child view controller's view from hierarchy
inActiveVC.willMove(toParentViewController: nil)
inActiveVC.view.removeFromSuperview()
// call after removing child view controller's view from hierarchy
inActiveVC.removeFromParentViewController()
}
}
private func updateActiveViewController() {
if let activeVC = activeViewController {
// call before adding child view controller's view as subview
addChildViewController(activeVC)
activeVC.view.frame = contentView.bounds
contentView.addSubview(activeVC.view)
// call before adding child view controller's view as subview
activeVC.didMove(toParentViewController: self)
}
}
// UI elements
lazy var contentView: UIView = {
let tv = UIView()
tv.backgroundColor = UIColor.purple
tv.translatesAutoresizingMaskIntoConstraints = false
tv.layer.masksToBounds = true
return tv
}()
var segmentedController: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
activeViewController = firstViewController
checkIfUserIsLoggedIn()
view.addSubview(contentView)
setupProfileScreen()
let items = ["Travelers", "Me"]
segmentedController = UISegmentedControl(items: items)
navigationItem.titleView = segmentedController
segmentedController.tintColor = UIColor.black
segmentedController.selectedSegmentIndex = 0
// Add function to handle Value Changed events
segmentedController.addTarget(self, action: #selector(HomeController.segmentedValueChanged(_:)), for: .valueChanged)
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Sign Out", style: .plain, target: self, action: #selector(handleSignOut))
navigationItem.leftBarButtonItem?.tintColor = UIColor.black
}
// reference to collectionViewController
var travelersFeedVC: TravelersFeedVC!
func segmentedValueChanged(_ sender:UISegmentedControl!)
{
switch segmentedController.selectedSegmentIndex {
case 0:
activeViewController = firstViewController
case 1:
activeViewController = secondViewController
default: // Do nothing
break
}
}// secondViewcontroller在containerView中,其中的模态是从
class ProfileVC: UIViewController {
// button to present modal
lazy var placesButton: UIButton = {
let customButton = UIButton(type: .system)
customButton.backgroundColor = UIColor.clear
// customButton.frame = CGRect(x: 150, y: 50, width: 120, height: self.view.frame.height)
customButton.setTitle("## of Places", for: .normal)
customButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
customButton.setTitleColor(.white, for: .normal)
customButton.addTarget(self, action: #selector(handleShowPlacesVC), for: .touchUpInside)
return customButton
}()
// function to call to present modal
func handleShowPlacesVC() {
let placesVC = PlacesTableVC()
let navigationController = UINavigationController(rootViewController: placesVC)
present(navigationController, animated: true, completion: nil)
}//情态观点驳回
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "back", style: .plain, target: self, action: #selector(handleCancel))
}
// dismiss modal view to return to secondViewController in childViewController containerView
func handleCancel() {
dismiss(animated: true, completion: nil)
}发布于 2017-04-16 18:23:38
当关闭模态对话框时,将调用MainNavigationController中的MainNavigationController函数。在这里,您设置了一个新的homeController,它是childs。这将在设置为viewDidload的HomeController中触发firstViewController。尝试在那里设置一个断点,你就会看到它。
为了避免在viewDidAppear中创建内容,我建议使用viewDidLoad。
另一个提示:“解散”定义为:“取消视图控制器所呈现的视图控制器。”--例如,如果在您的模式vc之上打开警报,它将关闭警报,而不是模式视图(self)。一个正确的实现必须调用呈现控制器(打开它的控制器):"presentingViewController?.dismiss()“它在您的代码中工作,因为苹果已经实现了一个退步,因为没有任何显示,但它是一个陷阱,有时会引起一些麻烦。
发布于 2017-04-16 18:28:46
虽然您是从子视图控制器调用present,但它实际上并不处理演示文稿。来自苹果文档
调用此方法的对象可能并不总是处理表示的对象。每种表示风格都有不同的规则来规范其行为。例如,全屏演示必须由本身覆盖整个屏幕的视图控制器进行。如果当前视图控制器无法完成请求,则会将请求转发到视图控制器层次结构的最接近的父节点,后者可以处理或转发请求。
由于要保持活动视图控制器的引用,一种解决方案可能是在解雇时显式设置索引。
https://stackoverflow.com/questions/43440127
复制相似问题