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
Related
The collectionView shows cells without any problem except the spacing, some spacing are not equal to others, they are a little bit bigger than others. Even I set margin = 0, some spacing still comes out.
Here is the code:
let margin = 1
let cellSize = (size.width-margin*(cellsPerRow+1)) / cellsPerRow
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)
layout.itemSize = CGSize(width: cellSize, height: cellSize)
layout.minimumInteritemSpacing = margin
layout.minimumLineSpacing = margin
Thanks.
You need to define the cell size based on maximum (integer) width/height that fits your whole area, then take the "leftover" (=area_width_or_height - (cell_size*cell_amount) ) and divide it by two to get the size of margins you need to leave to left/right/top/bottom to make the grid even. Now you get your cells slightly random based on whether you round to lower or higher number.
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.
I am simply trying to draw a rectangle and placing it in the bottom left hand side of the screen
var rectW:CGFloat = CGFloat(200.0)
var rectH:CGFloat = ceil(self.frame.height * 0.15)
var rect = SKShapeNode(rectOfSize: CGSize(width: rectW, height: rectH));
let posX:CGFloat = 0.0 + (rect.frame.width / 2)
let posY:CGFloat = self.frame.height - (self.frame.height - rect.frame.height)
rect.position = CGPointMake(posX,posY)
rect.fillColor = SKColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
rect.lineWidth = 1
self.addChild(rect)
The issue is that even though i believe all the maths is correct the rectangle is about 38 points/pixels that are under the screen, as you can see from the image below (the white border shows the limit).
For your information here is an output of the positions, heights and widths.
PosX: 100.5
PosY: 117.0
Rect Width: 201.0
Rect Height: 117.0
Frame Height: 768.0
Frame Weight: 1024.0
If i simple take this line but add 38 points/pixels it works, but why? Is there something I am missing?
let posY:CGFloat = self.frame.height - (self.frame.height - rect.frame.height) + 38
I found the answer via the following two answers:
SpriteKit coordinate system messed up
Problems understanding coordinate system SpriteKit using Swift
The problem turns out to be with GameScene.sks having it's size set differently.
Open up GameScene.sks and go to 'Show SKNodeInspector' should be the third box in the top right hand side of the screen.
Then set the dimensions to 320 x 568
Save then run. Should be working.