美文网首页
swift 简一

swift 简一

作者: f8d1cf28626a | 来源:发表于2022-07-28 23:52 被阅读0次

    swift 设置阴影 & SnapKit & 横竖屏

    阴影的设置是通过layer的shadow设置的,其中offset为阴影的偏移量,探索下offset是如何影响阴影显示的

    定义6个按钮,分别表示width 和 height 从 5.0 至 -5.0的变化过程
    整体效果如下:

    【阴影图片】

    根据效果图,可以得出如下结论

    • 当width 为正数时,shadow向右偏移,为负数时,shadow向左偏移
    • 当height为正数时,shadow向下偏移,为负数时,shadow向上偏移

    阴影的设置代码如下

        fileprivate func setupShader(_ w: CGFloat, _ h: CGFloat, _ btn: UIButton){
            //设置阴影路径--避免离屏渲染
            let path = UIBezierPath(rect: btn.bounds)
            btn.layer.shadowPath = path.cgPath
            //设置阴影颜色
            btn.layer.shadowColor = UIColor.black.cgColor
            //设置透明度
            btn.layer.shadowOpacity = 0.5
            //设置阴影半径
            btn.layer.shadowRadius = 5.0
            //设置阴影偏移量
            btn.layer.shadowOffset = CGSize(width: w, height: h)
        }
    

    SnapKit 更新约束 & label宽度自适应

    创建约束

    phoneNumLabel.snp.makeConstraints { (maker) in
        maker.left.equalToSuperview().offset(16)
        maker.top.equalToSuperview().offset(16)
        maker.height.equalTo(18)
        maker.width.equalTo(180)
    }
    

    更新约束有两种方式

    • 在原有约束的基础上更新:更新left
    phoneNumLabel.snp.makeConstraints { (maker) in
        maker.left.equalToSuperview().offset(100)
    }
    
    • 重新设置约束 remakeConstraints
    phoneNumLabel.snp.remakeConstraints { (maker) in
        maker.left.equalToSuperview().offset(50)
        maker.top.equalToSuperview().offset(50)
        maker.height.equalTo(30)
        maker.width.equalTo(100)
    }
    

    label自适应

    • 当只有一个label时,不设置宽度即可
    phoneNumLabel.snp.makeConstraints { (maker) in
        maker.left.equalToSuperview().offset(16)
        maker.top.equalToSuperview().offset(16)
        maker.height.equalTo(18)
    }
    
    • 当有两个label时,优先让其中一个宽度自适应
    //设置phoneNumLabel的宽度优先自适应,关键代码!!!
    phoneNumLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .horizontal)
    
    phoneNumLabel.snp.makeConstraints { (maker) in
        maker.left.equalTo(callIconImage.snp_right).offset(16)
        maker.top.equalToSuperview().offset(16)
        maker.height.equalTo(18)
    }
            
    callIdentifier.snp.makeConstraints { (maker) in
        maker.left.equalTo(phoneNumLabel.snp_right).offset(8)
        maker.top.equalTo(16)
        maker.height.equalTo(16)
    }
    

    Swift 横竖屏切换

    • 1、核心方法 viewWillTransition
    /// 切换横竖屏时,重设子view布局
    public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        ...
    }
    
    • 判断横竖屏方式一:
    if size.width > size.height { /// 横屏
        ...
    } else { /// 竖屏
        ...
    }
    
    • 判断横竖屏方式二:
    let orientation = UIApplication.shared.statusBarOrientation
    switch orientation {
        case .portrait, .portraitUpsideDown, .unknown: /// 竖屏
            ...
        case .landscapeLeft, .landscapeRight: /// 横屏
            ...
    }
    
    • 2、如何在横竖屏切换时更改 UI 细节

    以弹窗为例,UI 细节有:横屏居中显示,竖屏底部显示;弹窗高度,字体大小,UIView 的大小及 Offset。

    • 约束方式: 重点 remakeConstraints
    public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        ...
        container.snp.remakeConstraints { make in
    
          switch style {
    
          case .horizontal:
    
            make.center.equalToSuperview()
            make.width.equalTo(config.containerWidth)
    
          case .vertical:
    
            make.bottom.equalTo(view.snp.bottom)
            make.leading.trailing.equalToSuperview()
          }
          make.height.equalTo(config.containerHeight)
        }
        ...
    }
    
    • UIView 的宽高:
    /// 定义
    private var closeViewTopMargin: Constraint?
    private var closeViewRightMargin: Constraint?
    private var closeViewSize: Constraint?
    
    /// 赋值
    closeView.snp.makeConstraints { make in
      self.closeViewTopMargin = make.top.equalTo(background).offset(config.closeViewTopRightMargin).constraint
      self.closeViewRightMargin = make.trailing.equalTo(background).offset(-config.closeViewTopRightMargin).constraint
      self.closeViewSize = make.width.height.equalTo(config.closeViewSize).constraint
    }
    
    /// 更新
    public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        ...
        self.closeViewTopMargin?.update(offset: config.closeViewTopRightMargin)
        self.closeViewRightMargin?.update(offset: -config.closeViewTopRightMargin)
        self.closeViewSize?.update(offset: config.closeViewSize)
        ...
    }
    
    • 3、后续问题发现

    如果在两个类中使用 viewWillTransition 不起作用

    • 原因:当前的 ViewController 中复写了 viewWillTransition 方法,如果没有调用 super 方法,此消息不会再传递到下一个 ViewController 中

    解决方法:

    public override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
      super.viewWillTransition(to: size, with: coordinator)
      ...
    }
    
    • 如何让某个 ViewController 保持竖屏?

    AppDelegate:代码实现

    /// 全局变量
    var isAllowAutorotate: Bool = true
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
     ...
     func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?)
      -> UIInterfaceOrientationMask {
        if isAllowAutorotate {
          return [.portrait, .landscapeLeft, .landscapeRight]
        }
        else {
          return .portrait
        }
      }
     ...
    }
    

    使用 想要保持竖屏的 ViewController

    override func viewWillAppear(_ animated: Bool) {
      super.viewWillAppear(animated)
      isAllowAutorotate = false
    }
    
    override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      isAllowAutorotate = true
    }
    

    Swift 返回按钮

    • 1、左侧图标+文字
    private lazy var backButton: UIButton = {
        let button = UIButton()
        button.setImage(ImageLoader.image(named: "back"), for: .normal)
        button.imageView?.contentMode = .scaleAspectFit
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
        button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: -16)
        button.setTitle(NSLocalizedString("SETTINGS", comment: ""), for: .normal)
        button.addTarget(self, action: #selector(backOnTapped), for: .touchUpInside)
        button.setTitleColor(.mainTextColor, for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 18.0)
        return button
      }()
    
    • 2、左侧返回图标,标题居中
      public override func viewDidLoad() {
        ...
        navigationItem.titleView = titleView
        navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        ...
      }
      
      private lazy var titleView: UILabel = {
        let label = UILabel()
        label.text = NSLocalizedString("Add Friend", comment: "Add friend")
        label.textColor = .mainTextColor
        label.font = .systemFont(ofSize: 18.0)
        return label
      }()
    

    相关文章

      网友评论

          本文标题:swift 简一

          本文链接:https://www.haomeiwen.com/subject/pgefwrtx.html