CGRect X no effect in the TextField - ios

If you see my code I am trying to add 13 px padding from left of the city label in the textfield but it is not working. I am not sure what is going on there.
Here Is my textField
var cityTextField : RightPaddingTextField = {
var textField = RightPaddingTextField()
textField.textAlignment = .right
textField.translatesAutoresizingMaskIntoConstraints = false
var label = UILabel(frame: CGRect(x: 13, y: 0, width: 44, height: 44))
label.text = "City"
textField.leftViewMode = .always
textField.leftView = label
return textField
}()
Here setup constraints:
func cityLabelWithTextFieldSetup(){
addSubview(cityTextField)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0" : cityTextField]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0" : cityTextField]))
}
I am trying to achieve it like in this image but it's not working.
UPDATE
here is my code output please check only city row ..

Related

Swift 3 dynamic button height depends on title length in scrollable stackview

I want to create scrollview with radiobuttons/checkbox buttons. I tried different ways working with scrollview and stackview, but here are my issues:
Problem: multiline works fine, but button frame doesn`t work
Problem: multiline title and buttons dynamic height doesn't work; dynamic stackview height in scroll view works fine
Question: how can I make button depends on titleHeight works with scrollable stackview
private func testDynamicBtnHeight() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
mVScrollContainer.addSubview(scrollView)
mVScrollContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: .alignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
mVScrollContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: .alignAllCenterX, metrics: nil, views: ["scrollView": scrollView]))
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
scrollView.addSubview(stackView)
scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[stackView]", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))
scrollView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: NSLayoutFormatOptions.alignAllCenterX, metrics: nil, views: ["stackView": stackView]))
for i in 0 ... 30 {
var btn1 = RadioButtonMock.mockRadioButton(title: "A B C D", backgroundColor: UIColor.green)
var btn2 = RadioButtonMock.mockRadioButton(title: " 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ", backgroundColor: UIColor.red)
var btn3 = RadioButtonMock.mockRadioButton(title: "B B B B B B B", backgroundColor: UIColor.blue)
stackView.addArrangedSubview(btn1)
stackView.addArrangedSubview(btn2)
stackView.addArrangedSubview(btn3)
if i == 9 {
let url = URL(string: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQacMIFnZ2xZ_ZH7CjdUzzqpsMHwLSiF98lGWVWVHy6Am5qm2mq")
let data = try? Data(contentsOf: url!)
if let imageData = data {
let ivImage = UIImageView()
ivImage.image = UIImage(data: imageData)
ivImage.frame = CGRect(x: 0, y: 0, width: 100, height: 200)
stackView.addArrangedSubview(ivImage)
}
}
}
//mSvContainer.heightAnchor.constraint(equalToConstant: 400)
}
Radio button code:
static func mockRadioButton(title: String, backgroundColor: UIColor) -> RadioButton {
NSLog(TAG + " mockRadioButton(title: String, backgroundColor: UIColor)")
// min requirements to display simple checkBox
let rb = RadioButton()
rb.setTitle(title, for: .normal)
rb.setTitleColor(.black, for: .normal)
//cb.addTarget(self, action: #selector(checkBoxParamTap(sender:)), for: .touchUpInside)
rb.isChecked = false
rb.registerClickListener()
// title advanced
rb.titleLabel?.numberOfLines = 0 //multiline
//debug
rb.backgroundColor = backgroundColor
NSLog(TAG + "ccccc \(rb.bounds.size.height)")
//size
//rb.heightAnchor.constraint(equalToConstant: 30).isActive = true
//let contentSize = self.txtVDetails.sizeThatFits(self.txtVDetails.bounds.size)
//rb.frame = CGRect(x: 10, y: 10, width: 200, height: 50) //doesnt work
rb.heightAnchor.constraint(equalToConstant: 40).isActive = true //works fine
//rb.sizeToFit()
//rb.layoutIfNeeded()
rb.contentEdgeInsets.top = 8
//cb.contentEdgeInsets.right = 16
rb.contentEdgeInsets.left = 8
rb.contentEdgeInsets.bottom = 8
return rb
}

IOS 11 only: Navigation bar label off on top

IOS 11 is causing the main label to move a little bit from the top rather than keeping to the top. The problem only occurs on IOS 11. With different IOS everything looks ok.
Code sample with a setting header:
private func setHeader(agentName: String = "", isTyping: Bool = false) -> Void {
if (agentName.isEmpty) {
self.containerViewController?.navigationItem.titleView = nil
} else {
let headerView: UIView = {
let rect = CGRect(x: 0, y: 0, width: 320, height: 44)
let uiview = UIView(frame: rect)
return uiview
}()
let headerLabel: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: headerView.frame.width, height: 20))
label.font = UIFont.systemFont(ofSize: 18)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let subheaderLabel: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: headerView.frame.width, height: 12))
label.font = UIFont.systemFont(ofSize: 12)
label.translatesAutoresizingMaskIntoConstraints = false
label.text = self.title
return label
}()
headerView.addSubview(headerLabel)
headerView.addSubview(subheaderLabel)
let viewsDictionary = ["header": headerLabel, "subheader": subheaderLabel]
headerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[header]|", options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
headerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[subheader]|", options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
headerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[header(20)]-[subheader]", options: [], metrics: nil, views: viewsDictionary))
self.containerViewController?.navigationItem.titleView = headerView
}
}
Beginning with iOS 11, views add to toolbars are now laid out using auto layout. You should add sizing constraints on your headerView. For example:
headerView.widthAnchor.constraintEqualToConstant(320.0).isActive = true
headerView.heightAnchor.constraintEqualToConstant(44.0).isActive = true
Otherwise, auto layout will use the intrinsic content size of your header view which is likely not what you expect.
For more information see the WWDC 2017 session Updating your app for iOS 11.
#beyowulf said that you have to add sizing constraints. I think in your case adding height constraint is okay :
headerView.heightAnchor.constraint(equalToConstant: 22.0).isActive = true

Set top alignment for labels with different font sizes, Swift 3

I have seen similar SO questions with Objective C code, without much help.
I have 2 labels (currencyLabel, costLabel) with different font sizes, I would like them to be aligned to the top as you can see in the below picture. I tried by setting the same top spacing (viewHeight / 3) for both, but that doesn't seem to work.
Constraints are set in the last 4 lines of the code.
Please advice if there is a better approach to do this.
Here is the code:
override func viewDidLoad() {
super.viewDidLoad()
let viewWidth = self.view.bounds.width
let viewHeight = self.view.bounds.height
// 1. Creating Currency Label
currencyLabel = UILabel()
currencyLabel.numberOfLines = 1
currencyLabel.text = "$"
currencyLabel.textColor = Colors.curieBlue
currencyLabel.font = UIFont.systemFont(ofSize: 50)
// 1.1 Creating Cost Label
costLabel = UILabel()
costLabel.numberOfLines = 1
costLabel.text = "15"
costLabel.textColor = Colors.curieBlue
costLabel.font = UIFont.boldSystemFont(ofSize: 150)
// Disabling auto constraints
currencyLabel.translatesAutoresizingMaskIntoConstraints = false
costLabel.translatesAutoresizingMaskIntoConstraints = false
// Adding subviews to main view
self.view.addSubview(currencyLabel)
self.view.addSubview(costLabel)
let views = [
"currencyLabel" : currencyLabel,
"costLabel" : costLabel
] as [String : Any]
// Setting constraints for Cost Label
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-\(costLabelLeftSpacing)-[costLabel]", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(viewHeight / 3)-[costLabel]", options: [], metrics: nil, views: views))
// Setting constraints for Currency Label
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[currencyLabel]-10-[costLabel]", options: [], metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(viewHeight / 3)-[currencyLabel]", options: [], metrics: nil, views: views))
}
solution by programming:
you may use UILabel's attributed string property to handle this situation.
attribute options have one option named "NSBaselineOffsetAttributeName", it will render text offset the default baseline. and this offset can be measured through UIFont properties
offset = ascender - capHeight
code sample:
class CustomViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
let currencyLabel: UILabel = {
let label = UILabel()
let font = UIFont.systemFont(ofSize: 50)
// measure baseline offset
let offset = font.ascender - font.capHeight
label.attributedText = NSAttributedString(string: "$", attributes: [NSFontAttributeName: font, NSBaselineOffsetAttributeName: offset])
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.blue
return label
}()
let costLabel: UILabel = {
let label = UILabel()
let font = UIFont.systemFont(ofSize: 150)
let offset = font.ascender - font.capHeight
label.attributedText = NSAttributedString(string: "15", attributes: [NSFontAttributeName: font, NSBaselineOffsetAttributeName: offset])
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = UIColor.green
return label
}()
func setupViews() {
view.backgroundColor = UIColor.red
view.addSubview(currencyLabel)
view.addSubview(costLabel)
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[v0]-[v1]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": currencyLabel, "v1": costLabel]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-20-[v0]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": currencyLabel]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-20-[v0]", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": costLabel]))
}
}
result:
You can use align tool, next to pin tool, to add constraints between currency and value label. Align top edges of both the label. . Hope it helps!!
I did using below code:
let font:UIFont? = UIFont(name: "Helvetica", size:30)
let fontSuper:UIFont? = UIFont(name: "Helvetica", size:18)
let fontspace:UIFont? = UIFont(name: "Helvetica", size:8)
let attString:NSMutableAttributedString = NSMutableAttributedString(string: "₹ 6000.00", attributes: [.font:font!])
attString.setAttributes([.font:fontSuper!,.baselineOffset:8], range: NSRange(location:0,length:1))
attString.setAttributes([.font:fontspace!,.baselineOffset:8], range: NSRange(location:1,length:1))
attString.setAttributes([.font:fontSuper!,.baselineOffset:0], range: NSRange(location:attString.length-3,length:3))
lblPrice.attributedText = attString

UILabel vertical constraints with NSLayoutConstraints (swift 3 xcode)

Just started using NSLayoutConstraints and for some reason I can't get the vertical constraints to work. Whenever I run my application the label sits centered vertically in the view, regardless of what value I give it.
Here is the current code:
override func viewDidLoad() {
super.viewDidLoad()
print(self.view.bounds)
edgesForExtendedLayout = []
setupViews()
}
let headerTitleLabel: UILabel = {
let label = UILabel()
label.text = "Projects"
label.font = UIFont.boldSystemFont(ofSize: 14)
label.translatesAutoresizingMaskIntoConstraints = false
label.sizeToFit()
return label
}()
func setupViews() {
let v1 = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 200))
v1.backgroundColor = UIColor.red
self.view.addSubview(v1)
let v2 = UITableView(frame: CGRect(x: 0, y: v1.frame.height, width: view.bounds.width, height: (view.bounds.height-v1.frame.height)))
v2.backgroundColor = UIColor.blue
self.view.addSubview(v2)
v1.addSubview(headerTitleLabel)
v1.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-50-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": headerTitleLabel]))
v1.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-8-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": headerTitleLabel]))
}

Expandable cell, self sizing height

I made expandable view with dynamic amount of UILabels (created progammatically according to the count of results query produces). However I am not able to resize the expanded view height according to how many UILabels I have in the expanded view.
Using for loop I make as many labels as there are results after query.
Now I put them into view like this:
for (index, _) in timesBetween2Stations.enumerated() {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 20))
cell.ExpandableView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.center = CGPoint(x: cell.ExpandableView.frame.width / 2, y: 0)
label.textAlignment = NSTextAlignment.center
var substationTime = timesBetween2Stations[index]?.time
let substation = timesBetween2Stations[index]?.station
substationTime = substationTime!.removeTrainTimeZeros()
label.text = substation! + " " + substationTime!
cell.ExpandableView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[label]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["label": label, "expandable": cell.ExpandableView]))
if (previousLabel == nil){
cell.ExpandableView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(10)-[label]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["label": label, "expandable": cell.ExpandableView]))
}
else {
cell.ExpandableView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[previousLabel]-(10)-[label]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["label": label, "previousLabel": previousLabel as Any]))
}
previousLabel = label
}
Question is - why it's not resizing the view height according to the constraints? :)
Try this:
cell.setNeedsLayout()
cell.layoutIfNeeded()
or
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
after lor.

Resources