每次调用 Func 时都会重写 UIView

Posted

技术标签:

【中文标题】每次调用 Func 时都会重写 UIView【英文标题】:UIView is Being Over Written Every Time Func is Called 【发布时间】:2020-11-08 15:46:37 【问题描述】:

我的快速代码目标是在每次按下按钮时放置一个 uiview。在我的 gif 中,您可以看到每次调用蓝色按钮时它都会被覆盖。按下代码时,gif 中应该有 2 个 uiview。您可以看到第一个视图消失的透明uiview。基本上这段代码的所有问题是当调用 addBlackView 时,它应该添加到屏幕上的视图中,基本上就像一个无限数组一样。

import UIKit
class ViewController: UIViewController 

var image1Width2: NSLayoutConstraint!
var iHieght: NSLayoutConstraint!

override func viewDidLoad() 
    super.viewDidLoad()
    view.backgroundColor = .white

    view.addSubview(slider)
    slider.translatesAutoresizingMaskIntoConstraints = false
    slider.value = 0.5
    slider.isUserInteractionEnabled = true
    NSLayoutConstraint.activate([
        slider.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        slider.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        slider.heightAnchor.constraint(equalToConstant: 100),
        slider.widthAnchor.constraint(equalTo: view.widthAnchor,multiplier: 1),
    ])

    view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
        button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
        button.widthAnchor.constraint(equalToConstant: 100),
        button.heightAnchor.constraint(equalToConstant: 80),
    ])
    button.addTarget(self,action: #selector(addBlackView),for: .touchUpInside)
    slider.addTarget(self, action: #selector(increase), for: .allEvents)



let slider:UISlider = 
    let slider = UISlider(frame: .zero)
    return slider
()

private lazy var button: UIButton = 
    let button = UIButton()
    button.backgroundColor = .blue
    button.setTitleColor(.white, for: .normal)
    button.setTitle("add", for: .normal)
    return button
()

let blackView: UIView = 
    let view = UIView()
    view.backgroundColor = .black
    return view
()

@objc
private func addBlackView() 
    self.view.addSubview(blackView)
    blackView.translatesAutoresizingMaskIntoConstraints = false
    blackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    blackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    image1Width2 = blackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.1)
    image1Width2.isActive = true
    iHieght = blackView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.1)
    iHieght.isActive = true
    view.layoutIfNeeded()

    let recognizer = UIPanGestureRecognizer(target: self, action: #selector(moveView(_:)))
    blackView.addGestureRecognizer(recognizer)


@objc private func moveView(_ recognizer: UIPanGestureRecognizer) 
    switch recognizer.state 
    case .began:
        print("gesture began")
    case .changed:
        let translation = recognizer.translation(in: self.view)

        recognizer.view!.center = .init(x: recognizer.view!.center.x + translation.x,
                                        y: recognizer.view!.center.y + translation.y)
        recognizer.setTranslation(.zero, in: self.view)
    default:
        break
    


@objc func increase() 
    image1Width2.constant = CGFloat(slider.value) * view.frame.size.width * 0.10
    iHieght.constant = CGFloat(slider.value) * view.frame.size.width * 0.10

【问题讨论】:

【参考方案1】:

问题是您每次执行blackView 时都在重用和重置blackView,因此您所做的更改将丢失(因此为什么在您按下按钮后视图会回到中心) .

您需要在addBlackView 中创建一个完整的新视图,这将是您正在操作的“当前视图”,然后向其中添加手势识别器。然后,一旦您再次执行addBlackView,“currentView”将被“验证”(存储在数组中或您需要对其进行的任何操作),然后您创建另一个进行操作。

类似这样的:

private func addBlackView() 
    let newBlackView = UIView(frame: CGRect(0, 0, 10, 10)) // whatever frame you want
    self.view.addSubview(newBlackView)
    self.currentView = newBlackView

【讨论】:

“ViewController”类型的值没有成员“currentView”时出现错误 'currentView' 只是我为一个可以保存您正在操作的当前黑色视图的属性编造的名称,您必须创建它。

以上是关于每次调用 Func 时都会重写 UIView的主要内容,如果未能解决你的问题,请参考以下文章

为啥每次选择另一个 TextField 时都会调用 KeyboardWillShowNotification?

每次渲染正文时都会调用 SwiftUI Picker onReceive()

每次设置状态时都会调用 Flutter 函数

Angular2,为啥每次移动鼠标时都会调用函数

viewDidLoad 中的代码每次调用时都会运行

Angular Service 在每次调用时都会重置