微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

滑块导致初始化的约束被恢复

如何解决滑块导致初始化的约束被恢复

当我使用滑块时,它会恢复到原来的位置。我不知道增加函数中发生了什么导致这样做。我想将初始化约束保留在我不希望它们删除代码中。我只希望当用户更改对象滑块的值时,不要恢复到原始位置。您可以在 gif 中看到发生了什么。

enter image description here

import UIKit

class ViewController: UIViewController {
    
    var slizer = UiSlider()
    var oldCons = [NSLayoutConstraint]()
    var viewDrag = UIImageView()
    var panGesture = UIPanGestureRecognizer()
    
    var widthConstraints: NSLayoutConstraint?
    var tim: CGFloat = 50.0
    var slidermultiplier: CGFloat = 0.6
    override func viewDidLoad() {
        super.viewDidLoad()
        widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
        
        
        [viewDrag,slizer].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
        }
        
        NSLayoutConstraint.activate([
            
            
            slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),])
        
        
        slizer.addTarget(self,action: #selector(increase),for: .valueChanged)
        viewDrag.backgroundColor = .orange
        
        viewDrag.frame = CGRect(x: view.center.x-view.frame.width * 0.05,y: view.center.y-view.frame.height * 0.05,width: view.frame.width * 0.1,height: view.frame.height * 0.1)
        panGesture = UIPanGestureRecognizer(target: self,action: #selector(ViewController.draggedView(_:)))
        viewDrag.isUserInteractionEnabled = true
        viewDrag.addGestureRecognizer(panGesture)
        
        
        
    
        
        
        oldCons = [
            viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor),viewDrag.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: tim),viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),widthConstraints!,]
        NSLayoutConstraint.activate(oldCons)
        
        
    }
    
    
    @objc func sliderr() {
        
        
        
        NSLayoutConstraint.deactivate(oldCons)
        
        
        
        oldCons = [
            viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor),viewDrag.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant: -tim),]
        
        NSLayoutConstraint.activate(oldCons)
    }
    @objc func draggedView(_ sender: UIPanGestureRecognizer) {
        self.view.bringSubview(toFront: viewDrag)
        let translation = sender.translation(in: self.view)
        viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x,y: viewDrag.center.y + translation.y)
        sender.setTranslation(CGPoint.zero,in: self.view)
        
        
        
        
        
    }
    
    
    
    @objc func increase() {
        slidermultiplier = CGFloat(slizer.value)
        widthConstraints?.isActive = false
        widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
        widthConstraints?.isActive = true
    }
    
}

解决方法

视图“恢复”的原因是因为你给了 viewDrag 自动布局约束......但是在你的 draggedView 函数中,你明确地设置了它的框架(使用 viewDrag.center = CGPoint(...)) .

这不会改变它的约束,一旦你做其他事情来导致它更新,UIKit 会根据它的约束重新定位/重新调整它的大小。

不是设置 .centerviewDrag 属性,而是为 Lead 和 CenterY(定位)创建变量约束,并更新它们的 .constant 值以移动视图。

看看这个 - 里面有很多评论来帮助说明问题:

class SlideViewController: UIViewController {
    
    var slizer = UISlider()
    var viewDrag = UIImageView()

    var panGesture = UIPanGestureRecognizer()
    
    // Width,Leading and CenterY constraints for viewDrag
    var widthConstraints: NSLayoutConstraint!
    var viewDragLeadingConstraint: NSLayoutConstraint!
    var viewDragCenterYConstraint: NSLayoutConstraint!
    
    var tim: CGFloat = 50.0
    var slidermultiplier: CGFloat = 0.6
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        [viewDrag,slizer].forEach{
            $0.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview($0)
        }
        
        NSLayoutConstraint.activate([
            slizer.bottomAnchor.constraint(equalTo: view.bottomAnchor),slizer.leadingAnchor.constraint(equalTo: view.leadingAnchor),slizer.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.2),slizer.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),])
        
        slizer.addTarget(self,action: #selector(increase),for: .valueChanged)

        viewDrag.backgroundColor = .orange

        // no point setting a frame,since
        //  viewDrag has .translatesAutoresizingMaskIntoConstraints = false
        //viewDrag.frame = CGRect(x: view.center.x-view.frame.width * 0.05,y: view.center.y-view.frame.height * 0.05,width: view.frame.width * 0.1,height: view.frame.height * 0.1)
        
        // start with viewDrag
        //  width = "slidermultiplier" percent of view width
        widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
        // Leading = "tim" pts from view leading
        viewDragLeadingConstraint = viewDrag.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: tim)
        //  centered vertically
        viewDragCenterYConstraint = viewDrag.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        
        NSLayoutConstraint.activate([
            
            // viewDrag height will never change,so we can set it here
            viewDrag.heightAnchor.constraint(equalTo: view.heightAnchor,multiplier: 0.3),// activate the 3 "modifiable" constraints
            widthConstraints,viewDragLeadingConstraint,viewDragCenterYConstraint,])
        
        panGesture = UIPanGestureRecognizer(target: self,action: #selector(draggedView(_:)))

        viewDrag.isUserInteractionEnabled = true
        viewDrag.addGestureRecognizer(panGesture)
        
        // start the slider at the same percentage we've used
        //  for viewDrag's initial width
        slizer.value = Float(slidermultiplier)
        
    }
    
    @objc func draggedView(_ sender: UIPanGestureRecognizer) {
        // old swift syntax
        //self.view.bringSubview(toFront: viewDrag)
        self.view.bringSubviewToFront(viewDrag)
        
        let translation = sender.translation(in: self.view)
        viewDragLeadingConstraint.constant += translation.x
        viewDragCenterYConstraint.constant += translation.y
        
        // don't do this
        //viewDrag.center = CGPoint(x: viewDrag.center.x + translation.x,y: viewDrag.center.y + translation.y)
        
        sender.setTranslation(CGPoint.zero,in: self.view)
    }
    
    @objc func increase() {
        // get the new value of the slider
        slidermultiplier = CGFloat(slizer.value)
        
        // deactivate widthConstraints
        widthConstraints.isActive = false
        // create new widthConstraints with slider value as a multiplier
        widthConstraints = viewDrag.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: slidermultiplier)
        // activate the new widthConstraints
        widthConstraints.isActive = true
    }
    
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。