Ios 这是一种通过触摸导航栏中间的按钮来显示视图并通过触摸其他任何位置来移除视图的好方法吗?
我试图在导航栏的中间放一个按钮,当我触摸它时,它会显示一个列表(我在这里添加了一个纯UIView,而不是UITableView,只是为了简化代码)。然后,当我触摸其他任何地方时,附加视图将被删除。因此,我添加了一个与屏幕大小相同的背景视图来响应我的触摸。虽然它仍然在导航栏后面。 这是我的问题:Ios 这是一种通过触摸导航栏中间的按钮来显示视图并通过触摸其他任何位置来移除视图的好方法吗?,ios,swift,uinavigationcontroller,uinavigationbar,Ios,Swift,Uinavigationcontroller,Uinavigationbar,我试图在导航栏的中间放一个按钮,当我触摸它时,它会显示一个列表(我在这里添加了一个纯UIView,而不是UITableView,只是为了简化代码)。然后,当我触摸其他任何地方时,附加视图将被删除。因此,我添加了一个与屏幕大小相同的背景视图来响应我的触摸。虽然它仍然在导航栏后面。 这是我的问题: 这是一个好的实现吗 class ViewController: UIViewController { var optionView: UIView! var backgroundView:
这是一个好的实现吗
class ViewController: UIViewController {
var optionView: UIView!
var backgroundView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.addTarget(self, action: #selector(ViewController.titleButtonTapped), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 20, height: 30)
button.backgroundColor = .red
navigationItem.titleView = button
}
func titleButtonTapped() {
backgroundView = UIView(frame: UIScreen.main.bounds)
backgroundView.backgroundColor = .clear
let gesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleGesture)) // add this gesture to response my touch
backgroundView.addGestureRecognizer(gesture)
view.addSubview(maskView)
optionView = UIView(frame: CGRect(x: -40, y: 30, width: 100, height: 100)) // x = button.wdith / 2 - optionView.width / 2
optionView.backgroundColor = .red
navigationItem.titleView?.addSubview(alertView)
}
func handleGesture() {
optionView.removeFromSuperview()
backgroundView.removeFromSuperview()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
现在它看起来如下所示。
编辑:
下面是我对popover视图的实现
func buttonTapped() {
let popoverViewController = UIViewController()
popoverViewController.preferredContentSize = CGSize(width: 300, height: 300)
popoverViewController.modalPresentationStyle = .popover
let presentationController = popoverViewController.popoverPresentationController!
presentationController.delegate = self
presentationController.sourceView = view
presentationController.sourceRect = CGRect(x: 100, y: 100 , width: 100, height: 100)
present(popoverViewController, animated: true, completion: nil)
}
// delegate
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
这与苹果的文档有点不同。他们建议我们最好在调用present(:animated:completion:)方法后配置presentation控制器。但如果我在演示之前不配置它,它就不起作用。也许,因为我设置了代理
在调用present(quo;animated:completion:)之后配置popover演示控制器可能看起来有点违反直觉,但UIKit在您启动演示之前不会创建演示控制器。此外,UIKit必须等到下一个更新周期才能在屏幕上显示新内容。该延迟使您有时间为popover配置演示控制器
是否使用弹出视图,取决于此弹出视图的用途。如果它有很多信息,最好将其分离到另一个视图控制器,并在单击按钮时切换到它。这将为用户提供全屏幕查看任何内容。 对我来说,在导航栏的中心添加一个按钮并不常见。你必须通知我,让我点击它 总之: 如果您希望一个popover视图告诉用户提示或向他们显示一些内容,最好使用
UIPopopOverpresentationController
,这样您就不需要关心样式了
如果您希望另一个视图显示数据、图片列表等,最好使用分段控件或另一个视图控制器
uipopresentationcontroller
非常完美!上面的编辑部分是新代码。谢谢
var optionView: UIView!
var backgroundView: UIView!
override func viewDidLoad()
{
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
let button = UIButton(type: .system)
button.addTarget(self, action: #selector(ViewController.titleButtonTapped), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 20, height: 30)
button.backgroundColor = .red
navigationItem.titleView = button
}
func titleButtonTapped()
{
if backgroundView == nil
{
backgroundView = UIView(frame: UIScreen.main.bounds)
backgroundView.backgroundColor = .clear
let gesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleGesture)) // add this gesture to response my touch
backgroundView.addGestureRecognizer(gesture)
view.addSubview(backgroundView)
}
if optionView == nil
{
optionView = UIView(frame: CGRect(x: -40, y: 30, width: 100, height: 100)) // x = button.wdith / 2 - optionView.width / 2
optionView.backgroundColor = .red
navigationItem.titleView?.addSubview(optionView)
}
}
func handleGesture()
{
if optionView != nil
{
optionView.removeFromSuperview()
optionView = nil
}
if backgroundView != nil
{
backgroundView.removeFromSuperview()
backgroundView = nil
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}