ios - Swift:更改 UIView 框架但显示不更新

标签 ios swift uiview uiimageview frame

我正在尝试动态调整 UIView 框架的大小。我可以更新代码中的框架并看到值已更改,但实际显示永远不会改变,即使我运行 setNeedsDisplay()。

我正在关注 this post ,我通过 CGRectMake 定义了一个新框架,然后将 UIView 的框架设置为这个新框架。即,我正在这样做......

let newFrame = CGRectMake(minX,minY, width, height)
VUBarCover.frame = newFrame

如果我打印出 UIView 框架的值,我会看到它正在按我喜欢的方式变化。但显示(在模拟器中)从不反射(reflect)这些变化。

知道如何解决这个问题吗?

更新:更详细地说:我试图以编程方式用另一个 UIView 覆盖一个。它是一个水平的“VU Meter”,由一个显示颜色渐变的基本 UIImageView 组成,它被一个黑色背景的 UIView 部分动态“覆盖”。 UIImageView "VUBarImageView"在 StoryBoard 中定义,受 AutoLayout 约束。黑色 UIView“VUBarCover”完全以编程方式定义,没有 AutoLayout 约束。

为了完整性,这里是代码的相关部分...我遇到的麻烦是在 updateVUMeter()...

@IBOutlet weak var VUBarImageView: UIImageView!
var VUBarCover : UIView!

// this gets called after AutoLayout is finished
    override func viewDidLayoutSubviews() {
        // cover up VU Meter completely
        let center = VUBarImageView.center
        let width = VUBarImageView.frame.width
        let height = VUBarImageView.frame.height
        let frame = VUBarImageView.frame
        VUBarCover = UIView(frame: frame)
        MainView.addSubview(VUBarCover)
        VUBarCover.backgroundColor = UIColor.blueColor() // use black eventually. blue lets us see it for testing
    }

 // partially cover up VUBarImage with black VUBarCover coming from the "right"
func updateVUMeter(inputValue:Float) {   //inputValue is in dB

    //let val = pow(10.0,inputValue/10)  // convert from dB
    let val = Float( Double(arc4random())/Double(UInt32.max) ) //for Simulator testing, just use random numbers between 0 and 1
    print("val = ",val)

    let fullWidth = VUBarImageView.frame.width
    let maxX = VUBarImageView.frame.maxX
    let width = fullWidth * CGFloat(1.0-val)
    let minX = maxX - width
    let minY = VUBarImageView.frame.minY
    let height = VUBarImageView.frame.height

    let newFrame = CGRectMake(minX,minY, width, height)
    VUBarCover.frame = newFrame
    VUBarCover.setNeedsDisplay()

    print("fullWidth = ",fullWidth,"width = ",width)
    print(" newFrame = ",newFrame,"VUBarCover.frame = ",VUBarCover.frame)
}

样本结果是:

val =  0.9177
fullWidth =  285.0 width =  23.4556210041046
newFrame =  (278.544378995895, 93.5, 23.4556210041046, 10.0) VUBarCover.frame =  (278.544378995895, 93.5, 23.4556210041046, 10.0)
val =  0.878985
fullWidth =  285.0 width =  34.4891595840454
newFrame =  (267.510840415955, 93.5, 34.4891595840454, 10.0) VUBarCover.frame =  (267.510840415955, 93.5, 34.4891595840454, 10.0)
val =  0.955011
fullWidth =  285.0 width =  12.8218790888786
newFrame =  (289.178120911121, 93.5, 12.8218790888786, 10.0) VUBarCover.frame =  (289.178120911121, 93.5, 12.8218790888786, 10.0)

...也就是说,我们看到 VUBarCover.frame 正在“内部”改变,但在屏幕上它永远不会改变。我们看到的是全尺寸封面,完全覆盖了下面的图像(大约 300 像素宽),尽管它的宽度应该只有大约 12 像素)。

即使我在 VUBarCover 的 super View 上执行 setNeedsDisplay(),也没有任何变化。

帮助?谢谢。

最佳答案

首先,你有几个错误值得注意:

  • 实例变量(如 VUBarCoverMainView 应始终以小写字母开头(如 mainView)。
  • 您应该在覆盖实现开始时调用 super.viewDidLayoutSubviews()

其次,viewDidLayoutSubviews() 可以被调用任意次数,因此您对该方法的实现应该是 idempotent,这意味着无论调用多少次它都具有相同的效果次它被称为。但是当你打电话时:

VUBarCover = UIView(frame: frame)
MainView.addSubview(VUBarCover)

您正在创建一个 UIView 并将其添加到 View 层次结构中,以及您过去可能添加的其他 View 。所以它看起来框架没有在屏幕上更新。事实上,您只是无法分辨,因为 View 位于您正在更新的 View 之后,并且它们没有发生变化。

相反,您可能想创建一次:

var vuBarCover = UIView()

viewDidLoad()中将其添加为 subview :

mainView.addSubview(vuBarCover)

并在viewDidLayoutSubviews()中修改它的frame:

vuBarCover.frame = vuBarImageView.frame

您不需要调用 setNeedsDisplay()

关于ios - Swift:更改 UIView 框架但显示不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37682145/

相关文章:

objective-c - UIView animateWithDuration : duration: animations: completion: seems to have a default transition?

objective-c - @synthesize 创建什么 UIView setter

ios - 如何在 iOS 中跟踪表中的行选择事件

ios - 位置管理器 : sometimes startUpdatingLocation don't start

ios - 重复符号 Apple Mach-O 链接器错误

ios - Swift UI 在协议(protocol)中使用 View(协议(protocol) 'View' 只能用作通用约束,因为它有 Self 或关联的类型要求)

Swift 应用程序未从初始 ViewController 场景开始

ios - 检测 iOS UICollectionCell 何时离开屏幕

swift - 将所有项目放入一个 Collection View 行中

ios - 如何在 Swift 的未知宽度和高度的 View 中将 UIBezierPath 椭圆居中?