iOS PopupWindow与PopoverPresentationController使用

前言:
Android里有个控件叫做PopupWindow,在需要弹出视图的场景下特别方便,无论是布局还是事件响应都很简单。但iOS里面一开始并没有提供原生的类似控件。iPad里可以使用PopoverPresentationController来弹出一个小窗口,之后iOS9以后iPhone也支持该控件。实际上也可以通过使用单独的UIView来完成类似的效果,本文将浅析这些内容。

PopupWindow

原理:

自定义一个UIView,在该View上add控件,模拟VC。

这种方法很简单,有点类似系统提供的UIContainerView。但这里不提及后者的原因是因为一使用后者则母体VC的背景控制有些麻烦(弹出的弹出框边缘阴影效果),二是需要用到SB。采用前者除了没有独立的生命周期其余表现均可(依附于母体VC)。

代码:

import Foundation
import UIKit

class MyPopView: UIView{
    
    var contentView: UIView?{
        didSet{
            initView()
        }
    }
    
    override init(frame: CGRect){
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - Init view.
    func initView(){
        if self.contentView != nil {
            self.contentView?.frame.origin.y = UIScreen.main.bounds.size.height / 2
            self.addSubview(contentView!)
        }
        self.contentView?.layer.cornerRadius = 25
        self.backgroundColor = UIColor.white
        self.isUserInteractionEnabled = true
  //      self.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(dismissView)))
        
        installUIImageView()
        installUIButton()
    }
     
    func installUIImageView(){
        let imageView = UIImageView()
        imageView.frame = CGRect(x: ((self.contentView?.frame.width)! / 2) - 50, y: ((self.contentView?.frame.height)! / 2) - 60, width: 100, height: 100)
        imageView.image = UIImage(named: "ef")
        self.contentView?.addSubview(imageView)
    }
    
    func installUIButton(){
        let button = UIButton(type: .system)
        button.frame = CGRect(x: ((self.contentView?.frame.width)! / 2) - 25, y: ((self.contentView?.frame.height)! / 2) + 55, width: 50, height: 30)
        button.setTitle("Done", for: UIControl.State.normal)
        self.contentView?.addSubview(button)
    }
    
    // MARK: - Event block.
    @objc func show(){
        UIApplication.shared.keyWindow?.addSubview(self)
        UIView.animate(withDuration: 0.35, animations: {
            self.alpha = 1.0
            self.contentView?.frame.origin.y = UIScreen.main.bounds.size.height / 2
        })
    }
    
    @objc func dismissView(){
        UIView.animate(withDuration: 0.3, animations: {
            self.alpha = 0
        }) { (true) in
            self.removeFromSuperview()
            self.contentView?.removeFromSuperview()
        }
    }
}

效果:

在这里插入图片描述

PopoverPresentationController

这算是一个规规矩矩的模拟PopupWindow的一种方法了。下面是其代理:

UIPopoverPresentationControllerDelegate

func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
	// 弹出视图将要出现
}
func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
	// 弹出视图是否应该消失
}
func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
	// 弹出视图已经消失
}

使用前实现协议后要实现如下代理:

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return .none
}

下面是其基本属性:

  • sourceRect:弹出视图附带的箭头指向何处
  • sourceView:弹出视图附带的箭头指向何处,用于控件对象
  • canOverlapSourceViewRect:弹出视图是否可和箭头重叠
  • permittedArrowDirections:箭头方向
  • backgroundColor:弹出框背景颜色

代码:

弹出视图:

import UIKit

class PopViewController: UIViewController, UITextFieldDelegate{
    
    private func initView(){
        self.view.backgroundColor = UIColor.white
        
        var textField = UITextField(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 40))
        textField.delegate = self
        textField.placeholder = "Input some information."
        
        var imageView = UIImageView(image: UIImage(named: "ef"))
        imageView.frame = CGRect(x: (self.view.frame.width / 2) - 40, y: (self.view.frame.height / 2) + 25, width: 40, height: 40)
        self.view.addSubview(imageView)
        
        self.view.addSubview(textField)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        initView()
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        print("------> \(textField.text!)")
    }

}

启动视图:

        let popVC = PopViewController()
        popVC.modalPresentationStyle = .popover
        popVC.popoverPresentationController?.delegate = self
        popVC.popoverPresentationController?.sourceView = button
        popVC.popoverPresentationController?.sourceRect = button.bounds
        popVC.preferredContentSize = CGSize(width: self.view.bounds.width,height: self.view.frame.height)
        popVC.popoverPresentationController?.permittedArrowDirections = .unknown
        self.present(popVC, animated: true, completion: nil)

效果:

在这里插入图片描述

参考链接:https://zhuanlan.zhihu.com/p/265153923

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值