Swift label not fitting text correctly - swift

I'm trying create a label which will be able to display different movie titles of differing sizes. When I use the code below
lbl.numberOfLines = 3
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.05
I get the issue of longer words being split into multiple lines
See the issue below:
1st screen shot
When I use this code:
lbl.lineBreakMode = .byWordWrapping
lbl.numberOfLines = 3
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.05
I get the issue of words being missed out(the label is supposed to display the text "What's Love Got to Do With It")
See the issue below:
2nd screen shot
The label has a simple set of constraints
lbl.topAnchor.constraint(equalTo: countdownLbl.bottomAnchor, constant: 20).isActive = true
lbl.bottomAnchor.constraint(equalTo: btnStackView.topAnchor, constant: 20).isActive = true
lbl.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
lbl.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 20).isActive = true
Any help would be greatly appreciated.

Use option-return when typing in the little box in Interface Builder to insert a line feed (\n). In Interface Builder's Label attributes, set # Lines = 0.
Select the label and then change Lines property to 0.
like in the above image, and then use \n in your string for line break.

You select the label and then in the attributes inspector in the LINES property you leave it at 0 and the AUTOSHRINK property you leave it set to (minimum font scale)enter image description here

Related

Swift: UITableView Separator lines break layout constraints

So I have the following code that creates a TableView:
contentView.addSubview(carsTableView)
carsTableView.translatesAutoresizingMaskIntoConstraints = false
carsTableView.backgroundColor = r.darkGray
carsTableView.dataSource = self
carsTableView.isScrollEnabled = false
carsTableView.allowsSelection = true
carsTableView.delegate = self
carsTableView.separatorStyle = UITableViewCell.SeparatorStyle.singleLine
carsTableView.separatorColor = r.lightGray
carsTableView.separatorInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
carsTableView.register(CarCell.self, forCellReuseIdentifier: "CarCell")
Note that I use a single line separator. The following code are constraints for my Cell "CarCell"
NSLayoutConstraint.activate([
carView.heightAnchor.constraint(equalToConstant: 120),
carView.topAnchor.constraint(equalTo: contentView.topAnchor),
carView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
carView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
carView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
carImageView.leadingAnchor.constraint(equalTo: carView.leadingAnchor, constant: 15),
carImageView.centerYAnchor.constraint(equalTo: carView.centerYAnchor),
carImageView.heightAnchor.constraint(equalToConstant: carImageWidthAndHeight),
carImageView.widthAnchor.constraint(equalToConstant: carImageWidthAndHeight),
carImage.widthAnchor.constraint(equalTo: carImageView.widthAnchor),
carImage.heightAnchor.constraint(equalTo: carImageView.heightAnchor),
carImage.centerYAnchor.constraint(equalTo: carImageView.centerYAnchor),
carImage.centerXAnchor.constraint(equalTo: carImageView.centerXAnchor),
stringStack.leadingAnchor.constraint(equalTo: carImageView.trailingAnchor, constant: 20),
stringStack.centerYAnchor.constraint(equalTo: carView.centerYAnchor),
editButton.trailingAnchor.constraint(equalTo: carView.trailingAnchor, constant: -15),
editButton.centerYAnchor.constraint(equalTo: carView.centerYAnchor),
])
The result is a perfectly fine TableView which looks exactly like it should. However, the separator line breaks the height constraint from 120 to 120.33. How can I avoid that? I am honestly amazed by the fact that no one seems to have a similar problem. How do I get around it? The difference is obviously not noticeable, but the constraint issues bother me in the console. I'd like to have it run without throwing errors...
This is a common issue related to the way UIKit lays out table views and cells.
You're seeing 120 to 120.3333, but if you run the app on a device with #2x screen scale, the message will be 120.5.
When calculating "single pixel" lines, #2x devices can only use whole or 1/2 points, and #3x devices can only use whole, 1/3 or 2/3 points.
It is safe to ignore, but if you want to get rid of the error / warning messages, give your cells subview(s) a bottom constraint with less-than-required priority.
For example (I'm assuming from the code you posted that carImageView, carImage, stringStack, editButton are all subviews of carView):
let c = carView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
c.priority = .required - 1
NSLayoutConstraint.activate([
// don't use this one
//carView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
// activate the less-than-required bottom constraint
c,
// the rest of your constraints....
carView.heightAnchor.constraint(equalToConstant: 120),
carView.topAnchor.constraint(equalTo: contentView.topAnchor),
carView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
carView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
// and so on....

Height constraint, lessThanOrEqualToConstant, but tries to achieve the constant if possible

I have two views, previewSection, & settingsEditSection. I'm trying to layout these views to achieve the following:
previewSection's top is anchored to the top of the parent view
previewSection has a height of 400 if possible, but it will be smaller if necessary for settingsEditSection to achieve it's minimum height
settingsEditSection's top is anchored to bottom of previewSection
settingsEditSection's bottom is anchored to bottom of parent view
settingsEditSection has a height of at least 150
My problem is, when I give previewSection a height of lessThanOrEqualToConstant: 400 it has an actual height of 0.
Is there some way for me to say: "height of lessThanOrEqualToConstant, x, and as long as theres room, have the height of x"?
I want the height of 150 for settingsEditSection to be the first priority, and then before making it any larger, make previewSection 400 if possible, and if there's still room after that, then settingsEditSection can get larger than 150 to fill in the space.
Here's the code that I wrote, that makes the most sense to me:
let previewSection = PreviewSection()
view.addSubview(previewSection)
let settingsEditSection = SettingsEditSection()
view.addSubview(settingsEditSection)
// Preview section
previewSection.translatesAutoresizingMaskIntoConstraints = false
previewSection.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
previewSection.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
previewSection.topAnchor.constraint(equalTo: view.topAnchor, constant: topMargin).isActive = true
previewSection.heightAnchor.constraint(lessThanOrEqualToConstant: 400).isActive = true
previewSection.bottomAnchor.constraint(equalTo: settingsEditSection.topAnchor).isActive = true
// Settings & edit section
settingsEditSection.translatesAutoresizingMaskIntoConstraints = false
settingsEditSection.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
settingsEditSection.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
settingsEditSection.bottomAnchor.constraint(equalTo: upgradeButton.topAnchor).isActive = true
settingsEditSection.heightAnchor.constraint(greaterThanOrEqualToConstant: 150).isActive = true
settingsEditSection.topAnchor.constraint(equalTo: previewSection.bottomAnchor).isActive = true
Right now, previewSection has a height of 0, and then settingsEditSection's height just spans the entire parent view.
The context of this problem for me is I'm building out this profile page, and to layout the profile & buttons to look best on both an iPhone X and an iPhone 5S, this is the best way to do it.
You can use constraint priority here. After
previewSection.heightAnchor.constraint(lessThanOrEqualToConstant: 400).isActive = true
You can add one more constraint that gives a default height, but at a lower priority. Like this,
let previewSectionHeight = previewSection.heightAnchor.constraint(equalToConstant: 400)
previewSectionHeight.priority = .defaultHigh
previewSectionHeight.isActive = true
This will make previewSection to have a height of 400 until unless settingsEditSection pushes it up to make it small. For all of this to work you also need to give a constant height to the container view of previewSection and settingsEditSection.

Right upper constraint format

I am struggling with adding one button from code to the right corner of the view.
Could someone explain me how can i do this without setting the left constraint ? This would be the left upper V:|-10-[v0], H:|-10-[v0] what would be inversion of it ? I was trying with this : V:[v0]-10-|, H:[v0]-0-| but it does not work like i thought
Thanks in advance!
Based on the comments, I'd like to provide two answers on how to place a UIButton on the top right.
VFL:
Your vertical pin is for the bottom right, not the top. Instead of V:[v0]-10-|, where the "pipe" character (that designates the bounds of the screen) is at the end, place it at the beginning - |-10-[v0].
Provided you've given the button some sort of height/width - which I think you have as the code for "top left" works - this should fix things.
Anchors
Introduced in iOS9, layout anchors (along with layout guides) are a third way to code auto layout. Like NSLayoutConstraints, this is less "visual" than VFL. But unlike NSLayoutConstraints it's less verbose - thus more "Swiftier" IMHO.
To pin a UIButton to the top left, you still need to give auto layout four things - height, width, and X/Y positions. In the following I'm assuming the superview of v0 is called view, like the root view of a UIViewController.
// declare your button
let v0 = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
// remember, you ALWAYS need to turn of the auto resize mask!
v0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v0)
// create a square button
v0.widthAnchor.constraint(equalToConstant: 100.0).isActive = true
v0.heightAnchor.constraint(equalToConstant: 100.0).isActive = true
// pin the button 10 points from the left side of the view
v0.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
// here's how you would pin the button 10 points from the right side of the view
// note the use of a negative here!
// v0.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
// pin the button 10 points from the top of the view
v0.topAnchor.constraint(equalTo: view.topAnchor, constant: 10).isActive = true
}
Like NSLayoutConstraints, layout anchors have constants and multipliers, which you may change if you declare a name for the constraint.
You may combine NSLayoutConstraints with NSLayoutGuides for some nice "adaptive layouts". These guides act like "spacer/invisible" UIViews except for the overhead - they aren't views. You can get a set of Apple "standard" margins (UIView.layoutMarginsGuide), or you can create a set of equally size dynamic guides to space things out equally.
Here's two blogs about layout anchors and layout guides. The examples are written in Swift 2 but there's no syntax changes for Swift 3.

Remove Border and Margin around iOS Charts in Swift

I am using iOS Charts with Swift 3, and I can't figure out how to do a couple things:
I want to remove the margin around the chart. I know the chart goes edge-to-edge in my UI because if I change the chart's background color, it goes all the way to the edge. How do I remove the gap indicated by the red arrows below?
How do I remove the border around the whole graph (note the black arrow)? I already have totalsGraph.drawBordersEnabled = false and it doesn't work. Is there a different option for that?
Thank you!
It is minOffset.
/**
Sets the minimum offset (padding) around the chart, defaults to 10
*/
You can change it as this:
chartView.minOffset = 0
that line is actually axis line.
To hide the all the lines, you can use
totalsGraph.rightAxis.enabled = false
totalsGraph.legend.enabled = false
totalsGraph.leftAxis.enabled = false
totalsGraph.xAxis.labelPosition = .bottom
totalsGraph.xAxis.drawGridLinesEnabled = false
totalsGraph.xAxis.drawAxisLineEnabled = false
I am looking for solution to remove margins as well. I will update my answer when I find it.
Actually the way to do it is like this:
chartView.xAxis.enabled = false
chartView.leftAxis.enabled = false
chartView.rightAxis.enabled = false
chartView.drawBordersEnabled = false
chartView.minOffset = 0

How to hide labels in ios-charts?

I need disable some elements from my chart.
I used the iOS-charts library in (Swift 2), however I can't understand how to disable the following:
Hide right and left numbers
Hide description color square
Hide all vertical lines
self.chartView.xAxis.drawGridLinesEnabled = false
self.chartView.leftAxis.drawLabelsEnabled = false
self.chartView.legend.enabled = false
will do the job
self.chartView.drawEntryLabelsEnabled = false
This will hide the label from PieChart and shows only value. Also shows legend with label texts.
For only hide the top one:
graphCell.lineChartView.leftAxis.drawTopYLabelEntryEnabled = false