[英]Swift 2 - SWRevealViewController: Remove interaction on frontview when menu is open
I've implemented SWRevealViewController for a slide-out menu in my Swift app. 我已经在我的Swift应用程序中为滑出菜单实现了SWRevealViewController。 One issue with this framework is that when the menu (rearView) is expanded the user can still interact with the frontView. 该框架的一个问题是,当菜单(rearView)展开时,用户仍然可以与frontView进行交互。 Since my frontView is a full bleed map it's very difficult to close the menu by tapping on the frontView, because instead of recognizing it as a pan/tap to close it just moves the map around. 由于我的frontView是一个完整的出血地图,因此很难通过点击frontView来关闭菜单,因为与其将其识别为平移/轻按来关闭它,还不如将地图四处移动。
There is the same questions for Objective-C here . 没有为Objective-C的同样的问题在这里 。 The top answer from @hardluckbaby seems to be the best solution, but it's in Objective-C. @hardluckbaby的最高答案似乎是最好的解决方案,但这是在Objective-C中。 I've gotten the first part of the answer working in Swift, I need help with the second part. 我已经在Swift中获得了答案的第一部分,第二部分需要帮助。
In my rearView controller if added these two functions which successfully disable interactions on the frontView when the rearView (menu) is open: 在我的RearView控制器中,如果添加了这两个函数,则在打开RearView(菜单)时成功禁用frontView上的交互:
override func viewWillAppear(animated: Bool) {
self.revealViewController().frontViewController.view.userInteractionEnabled = false
}
override func viewWillDisappear(animated: Bool) {
self.revealViewController().frontViewController.view.userInteractionEnabled = true
}
This final part I need help converting to Swift. 这最后一部分我需要转换为Swift的帮助。 It's suppose to re-enable the pan/tap gestures for my frontView. 假设要为我的frontView重新启用平移/点击手势。 In my frontView I'm suppose to place the following in my ViewDidLoad function: 在我的frontView中,我想将以下内容放入ViewDidLoad函数中:
SWRevealViewController *revealController = [self revealViewController];
[revealController panGestureRecognizer];
[revealController tapGestureRecognizer];
How can this last part be written in Swift? 最后一部分如何用Swift编写?
I tried adding it to this function, but it doesn't recognize my taps. 我尝试将其添加到此功能中,但无法识别我的水龙头。 Do I need to take it out of this IF statement? 我是否需要将其从IF声明中删除?
override func viewDidLoad() {
super.viewDidLoad()
if self.revealViewController() != nil {
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
}
}
Found a different solution that still achieves the same result (disable interaction with frontView when rearView/menu is open). 找到了一个仍然可以达到相同结果的解决方案(在打开RearView /菜单时禁用与frontView的交互)。 It also has an additional benefit of "dimming" the frontView to focus the user on the menu. 它还具有“调暗” frontView以使用户集中在菜单上的其他好处。
There is no code needed in the menuController, I removed the code in viewWillAppear
and viewWillDisappear
that I referenced in my question. menuController中不需要任何代码,我删除了我在问题中引用的viewWillAppear
和viewWillDisappear
中的代码。
Below is what I added to my frontView controller. 以下是我添加到frontView控制器中的内容。 One downside is that this code needs to be included on all controllers that you want to disable interaction on when the menu is open. 缺点是,当菜单打开时,您要在其中禁用交互的所有控制器上都必须包含此代码。
Make sure to add SWRevealViewControllerDelegate
to where you declare your class. 确保在声明类的位置添加SWRevealViewControllerDelegate
。
Full frontViewController code: 完整的frontViewController代码:
// make sure to add SWRevealViewControllerDelegate to the class declaration
class LocationConfirmViewController: UIViewController, SWRevealViewControllerDelegate {
@IBOutlet weak var menuBtn: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
//menu button control
if self.revealViewController() != nil {
menuBtn.target = self.revealViewController()
menuBtn.action = "revealToggle:"
//new line to declare delegate
self.revealViewController().delegate = self
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
}
// MARK: - Navigation
//controls the frontView when the menu is opened.
//creates a mask that dims the view and blocks any interaction except for tap or pan to close the menu.
func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition){
let tagId = 4207868622
if revealController.frontViewPosition == FrontViewPosition.Right {
let lock = self.view.viewWithTag(tagId)
UIView.animateWithDuration(0.25, animations: {
lock?.alpha = 0
}, completion: {(finished: Bool) in
lock?.removeFromSuperview()
}
)
lock?.removeFromSuperview()
} else if revealController.frontViewPosition == FrontViewPosition.Left {
let lock = UIView(frame: self.view.bounds)
lock.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
lock.tag = tagId
lock.alpha = 0
lock.backgroundColor = UIColor.blackColor()
lock.addGestureRecognizer(UITapGestureRecognizer(target: self.revealViewController(), action: "revealToggle:"))
self.view.addSubview(lock)
UIView.animateWithDuration(0.5, animations: {
lock.alpha = 0.333
}
)
}
}
}
Credit to @mixth and his answer here to a similar question. 感谢@mixth和他在这里对类似问题的回答。 I made some changes and added more of a description on how to exactly implement. 我进行了一些更改,并添加了更多有关如何完全实现的描述。 Since I'm new to Swift I had trouble understanding his answer. 由于我是Swift的新手,所以我很难理解他的答案。 Hopefully this help others. 希望这可以帮助其他人。
您需要将该代码移到viewDidAppear
因为viewDidLoad
只会在第一次调用时调用,而其他功能将在每次视图重新显示在屏幕上时调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.