Frame on images and buttons - ios

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??

Related

Rectangle and button are skewed even they have same frame in Swift

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.

UIButton label showing three dots

I'm setting my button's title with this line of code:
self.timerButton.setTitle(String(Int(duration)), for: .normal)
The button is as large as 1/3 of the screen, the text size is 60, this was fine in my previous projects, but now with the value of duration changes ( from 120 ~ 0 ), the text often shows ... instead, sometimes even half of a number, what's wrong with this?
Here are the constraints shown in the debugger:
Try this it may help you :
self.timerButton.titleLabel?.adjustsFontSizeToFitWidth = true
#Deny's comment is very helpful, I looked into my constraints and found out I set the button's image size with this method:
self.contentEdgeInsets = UIEdgeInsets(top: (self.frame.height - imageSize) / 2, left: (self.frame.width - imageSize) / 2, bottom: (self.frame.height - imageSize) / 2, right: (self.frame.width - imageSize) / 2)
which cause the titleLabel's size to be smaller than it should be, so I changed the above code to this:
self.imageEdgeInsets = UIEdgeInsets(top: (self.frame.height - imageSize) / 2, left: (self.frame.width - imageSize) / 2, bottom: (self.frame.height - imageSize) / 2, right: (self.frame.width - imageSize) / 2)
then it worked.
TL;DR
The problem is caused by constraints.
Not a perfect solution but setting a width constraint forces the button to not scale down too much, like so:
myButton.translatesAutoresizingMaskIntoConstraints = false
myButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 180).isActive = true

Is there a way to convert coordinate points between different device sizes? (iOS)

I am following some tutorials online but the code is meant for an iPad. I am working with an iPhone and the screen sizes are different. The problem is that the author uses 'magic numbers' that are made specifically for the iPad.
I have been successful in creating conversions so that it will work for any device. For example:
let xMid : CGFloat = CGRectGetMidX(self.frame)
let yMid : CGFloat = CGRectGetMidY(self.frame)
print("x: \(xMid) y: \(yMid)")
let height : CGFloat = CGRectGetHeight(self.frame)
let width : CGFloat = CGRectGetWidth (self.frame)
makeSlotAt(CGPoint(x: xMid / 4.0, y: 0), isGood: true)
makeSlotAt(CGPoint(x: xMid - xMid / 4.0, y: 0), isGood: false)
makeSlotAt(CGPoint(x: xMid + xMid / 4.0, y: 0), isGood: true)
makeSlotAt(CGPoint(x: xMid * 2.0 - xMid / 4.0, y: 0), isGood: false)
makeBouncerAt(CGPoint(x: 0, y: 0))
makeBouncerAt(CGPoint(x: xMid / 2.0, y: 0))
makeBouncerAt(CGPoint(x: xMid, y: 0))
makeBouncerAt(CGPoint(x: xMid * 1.5, y: 0))
makeBouncerAt(CGPoint(x: xMid * 2.0, y: 0))
Anyway, I was just wondering if there was a function or cheat sheet that had numerical conversions between device sizes.
Thanks!
If the tutorial you're using uses magic numbers, then stop using it immediately. If you use autolayout and follow Apple's guidelines for iOS 7 & up, you rarely, if ever, need to use magic numbers. The functions that you created are a good start for in-code measurements.

How to make text the same size on all devices in SpriteKit?

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.

Resize parent UIView based on its children size

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.

Resources