I am trying to find the true position of a UIView named playingCardContainer. You are seeing a snap shot of what is to be a much larger switch case. I have added some text to try to debug and see whats going on. On a smaller screen this works correctly, On a bigger screen its breaking. Here are some screenshots from an Iphone 15 Pro simulator and Iphone SE Simulator. These screenshots are from the same code. playingCardContainer is in view with all the cards in it.
I have included case 4 as an example because some views are embedded in another view, we have to convert it. Which works fine on both Small and Big devices. Am I missing something?
The variable ClearPoint attempts finds the center of the UIView and from there we calculate where to draw it from, alternatively we can also get minx,miny. Nothing seems to be working.
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)
You can ignore this part of the code, its just hows its drawn on to the screen, all the necessary points are put on to it.
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
}
It looks like you're points are off because your leading and trailing bounds for your UI elements are different in devices with a safe area(iPhone 15) and those without(iPhone SE). There isn't enough code provided to pin down where the issue is but if you build you're UI using leading and trailing of the edges of the controller's view.layoutMarginsGuide
you should get the same result on devices with and without safe areas. The yellow areas in this screenshot illustrate the difference for your leading/trailing edges