UIView/StackView 框架返回错误的 .centers 在较大的屏幕上?

问题描述 投票:0回答:1

我试图找到名为playingCardContainer 的UIView 的真实位置。您正在看到一个更大的开关盒的快照。我添加了一些文本来尝试调试并查看发生了什么。在较小的屏幕上,它可以正常工作,在较大的屏幕上,它会崩溃。以下是 Iphone 15 Pro 模拟器和 Iphone SE 模拟器的一些屏幕截图。这些屏幕截图来自相同的代码。 PlayCardContainer 可见,其中包含所有纸牌。

我以案例 4 为例,因为有些视图嵌入到另一个视图中,我们必须对其进行转换。在小型和大型设备上都可以正常工作。我是不是错过了什么?

变量 ClearPoint 尝试找到 UIView 的中心,并从那里我们计算从哪里绘制它,或者我们也可以获取 minx,miny。似乎什么都不起作用。

case 3:
            //var clearPoint = playingCardContainer.center // similiar result
            //var clearPoint = playingCardContainer.convert(playingCardContainer.center, to: view.window) // completely wrong
            let containerFrame = playingCardContainer.frame
            let containerCenter = CGPoint(x: containerFrame.origin.x + containerFrame.width / 2, y: containerFrame.origin.y + containerFrame.height / 2)
            var clearPoint = view.convert(containerCenter, from: playingCardContainer.superview)
            
            let width: CGFloat = playingCardContainer.frame.width // Use the container's width
            let height: CGFloat = playingCardContainer.frame.height // Use the container's height
            let minX = containerFrame.minX
            let minY = containerFrame.minY
            //let minX = playingCardContainer.frame.minX
            //let minY = playingCardContainer.frame.minY
            let Text = UILabel(frame: CGRect(x: clearPoint.x, y: clearPoint.y, width: 50, height: 15))
            Text.text = "center"
            Text.textAlignment = .center
            
            let Text2 = UILabel(frame: CGRect(x: containerFrame.minX, y: containerFrame.minY, width: 50, height: 15))
            Text2.text = "Top left"
            Text2.textAlignment = .center
            Text2.textColor = .green
            
            view.addSubview(Text)
            view.addSubview(Text2)
            ShowUserGuide(atStep: 3, clearPoint: &clearPoint, containerWidth: width, containerHeight: height, minX: minX, minY: minY )
            
        case 4:
            var clearPoint = noDiscardsRemainingLabel.convert(noDiscardsRemainingLabel.center, to: view.window)
            let width: CGFloat = noDiscardsRemainingLabel.frame.width + 30  // Use the container's width
            let height: CGFloat = noDiscardsRemainingLabel.frame.height + 30 // Use the container's height
            ShowUserGuide(atStep: 4, clearPoint: &clearPoint, containerWidth: width, containerHeight: height)

你可以忽略这部分代码,它只是如何绘制到屏幕上的,所有必要的点都放在上面。

func ShowUserGuide(atStep:Int, clearPoint:inout CGPoint, containerWidth:CGFloat, containerHeight: CGFloat, adjustClearPoint:Bool = true , flipBox:Bool = false, minX:CGFloat = 0, minY:CGFloat = 0)
    {
        if flipBox
        {
            step0roundLabelView = RoundedTextLabel(frame: CGRect(x: view.frame.minX + 10, y: view.frame.maxY - 110, width: 300, height: 100), text: HowToPlayGuide.shared.getGuideText(atStep: atStep), textSize: 15)
        } else
        {
            step0roundLabelView = RoundedTextLabel(frame: CGRect(x: view.frame.maxX - 310, y: view.frame.maxY - 110, width: 300, height: 100), text: HowToPlayGuide.shared.getGuideText(atStep: atStep), textSize: 15)
        }
        view.addSubview(step0roundLabelView!)
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(DismissGuideView(_:)))
        tapGestureRecognizer.name = String(atStep)
        view.addGestureRecognizer(tapGestureRecognizer)
        let maskView = UIView(frame: view.bounds)
        let maskLayer = CAShapeLayer()
        if adjustClearPoint
        {
            clearPoint.y = clearPoint.y - 20
        }
        var maskRect:CGRect
        if minY != 0
        {
            maskRect = CGRect(x:minX, y: minY, width: containerWidth, height: containerHeight)
        } else
        {
            maskRect = CGRect(x: clearPoint.x - containerWidth / 2, y: clearPoint.y - containerHeight / 2, width: containerWidth, height: containerHeight)
        }
        print("maskRect = \(maskRect)")
        let maskPath = UIBezierPath(rect: maskView.bounds)
        //maskPath.addArc(withCenter: clearPoint, radius: 50, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
        maskPath.append(UIBezierPath(rect: maskRect))
        maskPath.usesEvenOddFillRule = true
        maskLayer.path = maskPath.cgPath
        maskLayer.fillRule = .evenOdd
        
        let animation = CABasicAnimation(keyPath: "path")
        animation.fromValue = lastMaskPath?.cgPath //UIBezierPath(rect: darkOverlayView!.layer.frame).cgPath
        animation.toValue = maskPath.cgPath //UIBezierPath(rect: maskRect).cgPath
        animation.duration = 1.0 // Set the animation duration
        maskLayer.add(animation, forKey: "pathAnimation2")
        
        darkOverlayView!.layer.mask = nil
        darkOverlayView!.layer.mask = maskLayer
        lastMaskPath = maskPath
    }
swift uiview uikit
1个回答
0
投票

看来您的观点有所偏差,因为您的 UI 元素的前导和尾随边界在具有安全区域的设备(iPhone 15)和没有安全区域的设备(iPhone SE)中是不同的。没有提供足够的代码来确定问题所在,但如果您使用控制器

view.layoutMarginsGuide
边缘的前导和尾随构建 UI,您应该在具有和不具有安全区域的设备上获得相同的结果。此屏幕截图中的黄色区域说明了前缘/后缘的差异

© www.soinside.com 2019 - 2024. All rights reserved.