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