I'm working on Swift 5 with Xcode 11.7 in a project. In here, I have a button and draw a rectangle around it. Everything is fine until I run it in iPhone 11 (11 pro, 11 pro max) simulator. Even I have set x,y of rectangle as same as the button's but they are skewed, other simulator didn't have this situation.
How can I fix this problem. Many thanks.
Question to me if it is not clear enough for you.
Here is my code to make a rectangle and make it around the button.
let rect = CGRect(x: btnSignIn2.frame.origin.x - 10, y: btnSignIn2.frame.origin.y + btnSignIn2.layer.bounds.height + 10, width: btnSignIn2.layer.bounds.width + 20, height: btnSignIn2.layer.bounds.height + 20)
let spotlight1 = AwesomeSpotlight(withRect: rect,
shape: .roundRectangle,
text: "message_please_login".localized(),
labelPosition: CGRect(x: 0, y: rect.maxY - btnSignIn2.layer.bounds.height + 25, width: UIScreen.main.bounds.width, height: 100),
isAllowPassTouchesThroughSpotlight: true)
The screenshot I put down here is the problem I have. The left side is iPhone11, and the other side is one of other simulator.
Related
What is the best manner to create a layout per device?
Right now i am working with constraints but i cant get it right.
The width/height from my so called gameView is to small to fit the puzzle pieces.
This is the right width/height to fit the puzzle pieces for the iPhone 11
And this is the view on the iPhone 8
Pieces
My solution to get it all fit is to set the frame sizes per device
But i don't know if it is the right solution.. I can imagine that there are better solutions..
if UIDevice.current.deviceCategory() == .iPhone8 {
turnOffConstraints()
topView.frame = CGRect(x: 0, y: 0, width: topView.frame.width, height: 70)
categoryLabel.frame = CGRect(x: 88, y: 23, width: 199, height: 35)
totalMovesSV.frame = CGRect(x: 308, y: 78, width: 50.5, height: 44)
timerSV.frame = CGRect(x: 20, y: 78, width: 50.5, height: 44)
gameView.frame = CGRect(x: 20, y: 130, width: 335, height: 335)
hintSV.frame = CGRect(x: 161, y: 473, width: 52, height: 80.5)
backButtonSV.frame = CGRect(x: 52, y: 8, width: 52, height: 80.5)
showOriginalButtonSV.frame = CGRect(x: 161, y: 8, width: 52, height: 80.5)
levelsButtonSV.frame = CGRect(x: 275, y: 8, width: 52, height: 80.5)
bottomView.frame = CGRect(x: 0, y: 567, width: topView.frame.width, height: 100)
}
The App is working and everything fits like i wanted but now my debugger is full with this kind of messages:
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2020-06-12 15:24:55.282095+0200 Sliding Game[35445:2539475] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
I am curious what the right approach is..
You give constant values to your all components.Its maybe looking good some devices but It doesnt mean looks fine in all.Lets say yout giving 160px height for a component. It will look ok on iPhone XsMax (height is 896px) almost One fifth of the screen. But when you run in iPhone 5, SE..(height is 568px) almost one fourth of the screen.
Giving constant value can occur intertwine of components. This is what Debug screen want to say.
You can estimate components to the screen or make anchor each other for avoiding it
I am trying to annotate a PDF using type .ink in my application using a UIBezierPath. I have included a snippet of the pertinent code below (can add the whole sample but issue is only with rotating the path). The issue is when I apply this path, it is rotated 180 degrees around the x- axis so basically it is flipped upside down. I would like to be able to rotate this path 180 degrees around the x-axis so it appears as initially intended. I have seen example of rotating around the z-axis but none around the x-axis. Any help would be greatly appreciated!
let rect = CGRect(x: 110, y: 100, width: 400, height: 300)
let annotation = PDFAnnotation(bounds: rect, forType: .ink, withProperties: nil)
annotation.backgroundColor = .blue
path.apply(CGAffineTransform(scaleX: 0.2, y: 0.2))
annotation.add(path)
// Add annotation to the first page
page.addAnnotation(annotation)
pdfView?.document?.page(at: 0)?.addAnnotation(annotation)
I was actually able to solve this issue using the following scale and a translation transforms:
let rect = CGRect(x: 110, y: 100, width: 400, height: 300)
let annotation = PDFAnnotation(bounds: rect, forType: .ink, withProperties: nil)
annotation.backgroundColor = .blue
// OVER HERE 🙂
path.apply(CGAffineTransform(scaleX: 1.0, y: -1.0))
path.apply(CGAffineTransform(translationX: 0, y: rect.size.height))
annotation.add(path)
// Add annotation to the first page
page.addAnnotation(annotation)
pdfView?.document?.page(at: 0)?.addAnnotation(annotation)
This solution is inspired from the Apple Developer Documentation example.
It was a bit tricky because the PDFKit Coordinate System uses the bottom/left as the origin, with the x- axis going left-to-right and the y- axis going bottom-to-top. That's contrary to the origin: top/left, x: left-to-right and y: top-to-bottom pattern usually encountered on iOS. But this is what we're doing:
CGAffineTransform(scaleX: 1.0, y: -1.0) - scaling the y coordinate to -1.0 makes your path flip 180 degrees around the x- axis (said axis visually being the bottom line of the rect). This means the path is now below of the rect, which might give you the impression that it has disappeared (you won't even find it by Capturing the View Hierarchy since it will show you the entire PDFView as one UIView component, which may or may not drive you insane).
CGAffineTransform(translationX: 0, y: rect.size.height) - now that the path is at the bottom of the rect (but actually at the "top" according to the PDFKit Coordinate System), we need to bring it back into the visible area. Which is why we need to apply a translation transform to move the path up (or down - thanks again PDFKit) into the rect.
Hope this helps! Cheers
I'm trying to set my buttons and images to be in a specific spot on all Iphone screen sizes. Normally I would use CGPoint(width: self.frame.width, height: self.frame.height) , but in buttons you use .Frame which is different, and I write .frame = CGRect(x: self.frame.width / 7.7, y: self.frame.height / 2.6, width: self.frame.width / 10, height: self.frame.height / 12)
, but it works on one screen for say iphone 6, but then on a iphone 5 it is in a different spot... any suggestions??
In SpriteKit, is there a way to make an SKLabelNode look the same size, regardless of the device, eg: Looks the same size on a iPhone 5 as a 6Plus?
I've tried using this method someone else recommended:
let textRect = CGRect(x: 0, y: 0, width: frame.width * 0.4, height: frame.height * 0.045)
let scalingFactor = min(textRect.width / text.frame.width, textRect.height / text.frame.height)
text.fontSize *= scalingFactor
But it doesn't make all text the same size, as words like "man" aren't as physically tall as words like "High" (due to it's "y" and "h" sticking out).
So is there a method to make text look the same size on all devices? At the moment I create the SKLabelNode like so:
let text = SKLabelNode(text: "Start")
text.fontSize = 30
text.position = CGPoint(x: 0, y: 0)
addChild(text)
The issue here is that you are trying to scale the fontSize, and this does not really play well with complex decimal numbers. Instead, after you create your label, just scale that to the scale factor that you are using to scale everything else
let text = SKLabelNode(text: "Start")
text.fontSize = 30
text.position = CGPoint(x: 0, y: 0)
text.xScale = xScaleFactor
text.yScale = yScaleFactor
where xScaleFactor and yScaleFactor are the factors you are using to determine your scale. (This number should only have to be calculated once, and then stored, if you are not doing that, I would recommend making that change)
Basically in the code you provided it is done like this:
let textRect = CGRect(x: 0, y: 0, width: frame.width * 0.4, height: frame.height * 0.045)
let scaleFactorX = textRect.width / text.frame.width
let scaleFactorY = textRect.height / text.frame.height
I think it's more like an algorithm question. Think about you need to implement the same thing in TV, iPad or in the iPhone device. You should think about storing its absolute value rather than its actual value.
The formula should be width for store value = actual width for this device / device width. The same with the height. Then, if you use the same image data in other devices. You will just need to multiply the new device width/height.
I'm new in iOS programming and still don't know how to handle correctly basic stuff like this so I hope someone has good practice to share.
I created a custom keyboard for the user to answer to a question.
It's an UIView containing some UIButton.
How does one center the whole keyboard?
I know I could calculate the width of the keyboard by adding up the width of each key but this seems quite complicated for such a simple action.
Here's my code (in Swift) for now, thanks.
keyboardContainer = UIView(frame: CGRectMake(0, 0, self.frame.width, 200))
keyboardContainer!.center = CGPoint(x: keyboardContainer!.frame.width / 2, y: self.frame.height - keyboardContainer!.frame.height / 2)
self.addSubview(keyboardContainer!)
let gap = Int(self.frame.width) / 8
for i in 0..<keyboardLetters!.count {
let posX = Int(i % 7) * gap + 22
let posY = Int(i / 7) * gap + 25
let key = Key(frame: CGRectMake(0, 0, 44, 44))
key.letter = keyboardLetters![i]
key.tag = i
key.center = CGPoint(x: posX, y: posY)
keyboardContainer!.addSubview(key)
key.addTarget(self, action: "onKeyboardTap:", forControlEvents: .TouchUpInside)
}
Move the center of keyboardContainer and all the buttons will move with it.