UILabel Position different than expected - ios

Im starting to dabble a bit with swift and ran into a weird behaviour and was wondering if someone could shed some light on why. Im trying to add a UILabel to a UIView and position it in the centre of the UIView. Theoretically this can be achieved with the following.
self.titleContainer = UIView(frame: CGRect(x: self.view.bounds.origin.x, y: self.view.bounds.origin.y
+ 20.0, width: self.view.bounds.width, height: (self.view.bounds.height * cSixth) - 20.0))
self.titleContainer.backgroundColor = UIColor.blackColor()
self.view.addSubview(titleContainer)
self.titleLabel = UILabel()
self.titleLabel.text = "Naughts and Crosses"
self.titleLabel.textColor = UIColor.whiteColor()
self.titleLabel.font = UIFont(name: "Helvetica", size: 10)
self.titleLabel.sizeToFit()
self.titleLabel.center = titleContainer.center
titleContainer.addSubview(self.titleLabel)
however this doesn't seem to take in the top margin. however the next block of code work and positions the label in the center.
self.titleContainer = UIView(frame: CGRect(x: self.view.bounds.origin.x, y: self.view.bounds.origin.y
+ 20.0, width: self.view.bounds.width, height: (self.view.bounds.height * cSixth) - 20.0))
self.titleContainer.backgroundColor = UIColor.blackColor()
self.view.addSubview(titleContainer)
self.titleLabel = UILabel()
self.titleLabel.text = "Naughts and Crosses"
self.titleLabel.textColor = UIColor.whiteColor()
self.titleLabel.font = UIFont(name: "Helvetica", size: 10)
self.titleLabel.sizeToFit()
self.titleLabel.center = CGPointMake(titleContainer.bounds.midX, titleContainer.bounds.midY)
titleContainer.addSubview(self.titleLabel)
Any ideas?
Thanks
Alec

I think you are mixing coordinate systems. self.titleLabel.center is a point inside titleContainer and titleContainer.center is a point inside [titleContainer superview].
The differences are explained in the View Programming Guide -> View and Window Architecture -> View Geometry and Coordinate Systems -> The Relationship of the Frame, Bounds, and Center Properties.

Related

UINavigationItem TitleView Cutting Off When Using UIView

I am trying to display a multi-line titleView in my app. Here is my code to set the titleView.
self.titleView = TitleView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: self.tableView.frame.width, height: 80)), title: "NEWS", subtitle: Date.dateAsStringForNavBarSubTitle())
self.titleView.backgroundColor = UIColor.red
self.navigationItem.titleView = self.titleView
The part of the implementation of TitleView is shown below:
private func setupUI() {
let label = UILabel(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: self.frame.width, height: self.frame.height)))
label.numberOfLines = 2
label.text = "\(self.title)\n\(self.subtitle)"
self.addSubview(label)
}
The label comes out to be outside the parent view.
Should I just use a UILabel instead of putting it in UIView?
I can see that you are adding label subview into title view. Instead, you can try this in your viewcontroller's viewDidLoad() method.
For Swift 4
let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: 44.0))
label.backgroundColor = .red
label.numberOfLines = 2
label.textAlignment = .left
label.text = "\(self.title)\n\(self.subtitle)"
self.navigationItem.titleView = label
For more information please refer this link UINavigationBar multi-line title

How to create a ruler / scale slider with Swift 3?

I'm trying to recreate a temperature ruler similar to the Coinbase app for an app in Swift 3. Unfortunately, I'm not sure if I follow the right approach.
In my current experiment, I used a UIScrollView element and placed / drawn lines at a certain distance (with a loop and UIBezierPath). In the next step I want to read the user input. With the current approach I have to use the X-position of the UIScrollView to convert things to read the current temperature. That seems to me a relatively inaccurate thing to be? My result looks like this.
// UI SCROLL VIEW
var scrollView: UIScrollView!
scrollView = UIScrollView(frame: CGRect(x: 0, y: 120, width: 400, height: 100))
scrollView.contentSize = CGSize(width: 2000, height: 100)
scrollView.showsHorizontalScrollIndicator = false
let minTemp = 0.0
let maxTemp = 36.8
let interval = 0.1
// LINES
let lines = UIBezierPath()
// DRAW TEMP OTHER LINES
for temp in stride(from: minTemp, to: maxTemp, by: interval)
{
let isInteger = floor(temp) == temp
let height = (isInteger) ? 20.0 : 10.0
let oneLine = UIBezierPath()
oneLine.move(to: CGPoint(x: temp*50, y: 0))
oneLine.addLine(to: CGPoint(x: temp*50, y: height))
lines.append(oneLine)
// INDICATOR TEXT
if(isInteger)
{
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 40, height: 21))
label.center = CGPoint(x: temp*50, y: height+15)
label.font = UIFont(name: "HelveticaNeue",
size: 10.0)
label.textAlignment = .center
label.text = "\(temp) °C"
scrollView.addSubview(label)
}
}
// DESIGN LINES IN LAYER
let shapeLayer = CAShapeLayer()
shapeLayer.path = lines.cgPath
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.lineWidth = 1
// ADD LINES IN LAYER
scrollView.layer.addSublayer(shapeLayer)
view.addSubview(scrollView)
self.view = view
The Coinbase app also struck me that there is some kind of adaptive feedback (at least on the iPhone X) when I move the slider. The iPhone vibrates easily when you come across a line, similar to the UIPickerView. I do not have that with my approach and I strongly doubt that the developer has programmed it in manually on Coinbase... So maybe there's a smarter, more up-to-date approach to how to recreate such a ruler natively in Swift?
you can using this pod
this will allow you to using that as horizontal or vertical
https://github.com/farshidce/RKMultiUnitRuler

Place label above each element in scrollview?

I'm populating my scrollview in a for loop and trying to place a UILabel on top of each inserted element. However, the label won't center horizontally for some reason even though I'm setting its centerXAnchor to be equal to each element's centerXAnchor. Here's a picture with the label and element's borders shown:
As seen, the label I'm inserting isn't being centered horizontally with each element in the scrollview for some reason. Here's my for loop where I populate the scrollview:
for i in 0..<petsDict.count {
let imageView = UIImageView()
imageView.image = petsDict[i]
imageView.contentMode = .scaleAspectFit
let xPos = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPos - CGFloat(20*i), y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
let label = UILabel(frame: CGRect(x: 0, y: -20, width: 200, height: 40))
label.text = "Joy"
label.textAlignment = .center
imageView.addSubview(label)
label.font = UIFont(name: "SFUIText-Regular", size: 20)!
label.sizeToFit()
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
label.centerXAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: imageView.topAnchor).isActive = true
}
Can anybody help me understand why my x centering isn't working properly?
Try to remove label.sizeToFit(), this function resizes your labels.
for i in 0..<petsDict.count {
let imageView = UIImageView()
imageView.image = petsDict[i]
imageView.contentMode = .scaleAspectFit
let xPos = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPos - CGFloat(20*i), y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
let label = UILabel(frame: CGRect(x: 0, y: -20, width: self.mainScrollView.frame.width, height: 20))
label.text = "Joy"
label.textAlignment = .center
imageView.addSubview(label)
label.font = UIFont(name: "SFUIText-Regular", size: 20)!
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
label.centerXAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: imageView.topAnchor).isActive = true
}
Try this code
Give width to label same as your imageview width and remove sizeToFit and anchor. You just need to add then textAlignment which you have already added.

swift 3 ios : UILabel

I'm trying to create a UILabel, with dynamic height
this is my code :
label1.text = Message
label1.textColor = UIColor.white
let font = UIFont.systemFont(ofSize: 17.0)
label1.font = font
label1.textAlignment = .center
label1.lineBreakMode = NSLineBreakMode.byWordWrapping;
label1.numberOfLines = 0;
label1.sizeToFit()
label1.frame = CGRect(x: 0, y:40 , width: 270, height: label1.frame.height)
however, my label stay with one line, where my Message is about 3 lines
so what could be the best solution for this problem?
The best solution would be using constraints.
Either directly in the InterfaceBuilder or via code.
(SnapKit would be a good and easy way to build constraints via code)
Try
let size = label1.sizeThatFits(CGSize(width: 270, height: 100000))
label1.frame = CGRect(x: 0, y: 40, width: 270, height: size.height)
for the last two line of your code.
you can do it with storyboard
label height relation to greater than or equal

how to place UILabel behind SKSpriteNode

i am trying to place a UILabel behind a SKSpriteNode. but what ever i try the label stays in front of the SpriteNode. z-index doesn't work and .movetoback also doesn't work.
could someone explain me how to do this?
You can add UILabel as a subview of SKView and adjust its position accordingly.
E.g. the following creates a white square sprite with an UILabel in front of it:
scene = SKScene(size: spriteView.bounds.size)
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
let sprite = SKSpriteNode(
color: SKColor.whiteColor(),
size: CGSize(width: 100, height: 100)
)
scene.addChild(sprite)
spriteView.presentScene(scene)
let frame = CGRect(
x: spriteView.bounds.midX - 50,
y: spriteView.bounds.midY - 50,
width: 100,
height: 100)
label = UILabel(frame: frame)
label.textAlignment = .Center
label.text = "Ook"
spriteView.addSubview(label)
P.S. I can not understand why would you want to use UILabel while SpriteKit has SKLabelNode which does practically the same but can be a part of the scene, so that will make your life easier in terms of adjusting positions.

Resources