Unable to modify UILabel frame inside UICollectionView? - ios

I have ViewController and inside it UICollectionView, I'm trying to add UILable to UICollectionView programmatically :
let Label: UILabel = {
let label = UILabel()
label.text = "Sample Text Here"
label.textAlignment = .center
label.textColor = UIColor(white: 0.4, alpha: 0.4)
label.font = UIFont.systemFont(ofSize: 20)
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
Label.translatesAutoresizingMaskIntoConstraints = false
Label.frame = CGRect(x: 0, y: 40, width: view.frame.width, height: 20)
collectionView.addSubview(Label)
}
when I tried to change the y value it's the same
when I tried to add it like this : view.addSubView(Label) didn't appear at all.
note: the label should appear if there's no data to populate the cells

It works..
override func viewDidLoad() {
super.viewDidLoad()
let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 300, height: 300), collectionViewLayout: UICollectionViewFlowLayout())
self.view.addSubview(collectionView)
collectionView.backgroundColor = UIColor.red
let label = UILabel()
label.text = "Sample Text Here"
label.textAlignment = .center
label.textColor = UIColor(white: 0.4, alpha: 0.4)
label.font = UIFont.systemFont(ofSize: 20)
label.frame = CGRect(x: 0, y: 100, width: view.frame.width, height: 20)
collectionView.addSubview(label)
}
Be careful with adding labels directly to the collectionview, though.
You could create a uiview and add both label to it and collection (with the appropriate collection view layout of course). Use collection view only for displaying cells and add anything to the cell.contentView if you wish
Thanks.

Related

Lable and button in the header section view UITableView

I am trying to add a section title Label and a button in the header section view. but it looks empty. when I run the application the header is empty. the 2nd section code work fine
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if (section == 0){
let label = UILabel.init(frame: CGRect.init(x: 17, y: 139, width: tableView.frame.size.width, height: 45))
label.textColor = UIColor.black
label.font = UIFont.systemFont(ofSize: 13.0)
label.textAlignment = .left
label.text = " My Balances"
label.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1.00)
let frame = tableView.frame
let height:CGFloat = 66
let button = UIButton(frame: CGRect(x: 306, y: 139, width: 15, height: 15)) // create button
button.tag = section
// the button is image - set image
button.setImage(UIImage(named: "remove_button"), for: .normal)
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: height)) // create custom view
headerView.addSubview(button) // add the button to the view
headerView.addSubview(label)
return headerView
//return label
//return label
}
else {
let label = UILabel.init(frame: CGRect.init(x: 0, y: 241, width: tableView.frame.size.width, height: 45))
label.textColor = UIColor.black
label.font = UIFont.systemFont(ofSize: 13.0)
label.textAlignment = .left
label.text = " My Customers"
label.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1.00)
return label
}
}
You are not following the proper way. First you have to set height of header view using heightForHeaderInSection from tableview object in viewDidLoad() like -
tableView.heightForHeaderInSection = 250
or by using its delegate method -
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 250
}
You set the height of header view equal to tableview height. Set it less than it let height:CGFloat = 250 -
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel.init(frame: CGRect.init(x: 0, y: 241, width: tableView.frame.size.width, height: 45))
label.textColor = UIColor.black
label.font = UIFont.systemFont(ofSize: 13.0)
label.textAlignment = .left
label.text = " My Balances"
label.backgroundColor = UIColor(red: 0.95, green: 0.95, blue: 0.95, alpha: 1.00)
let frame = tableView.frame
let height:CGFloat = 250
let button = UIButton(frame: CGRect(x: 5, y: 10, width: 15, height: 15)) // create button
button.tag = section
// the button is image - set image
button.setImage(UIImage(named: "remove_button"), for: .normal)
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: height)) // create custom view
headerView.addSubview(button) // add the button to the view
headerView.addSubview(label)
return headerView
//return label
}
Or another way is to make custom reusable header view, register as header view and finally dequeu it.
You can follow the documentation from apple for second way - https://developer.apple.com/documentation/uikit/views_and_controls/table_views/adding_headers_and_footers_to_table_sections

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 update CustomView width with different devices

I have a custom Button with 2 Labels and Image as shown in below class
import UIKit
#IBDesignable
class CustomButton : UIButton {
let secondLine : UILabel = UILabel()
override func layoutSubviews() {
super.layoutSubviews()
// self.layer.cornerRadius = 10
self.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
self.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.layer.shadowOpacity = 1.0
self.layer.masksToBounds = false
}
#IBInspectable var rightLebelText : String?{
didSet {
updateView()
}
}
func updateView(){
if let mytext = rightLebelText {
let firstLine = UILabel(frame: CGRect(x: self.bounds.size.width - 210, y: 0, width: 200, height: 40))
firstLine.text = mytext
firstLine.textAlignment = .right
firstLine.font = UIFont.systemFont(ofSize: 20)
self.addSubview(firstLine)
var imageView : UIImageView
imageView = UIImageView(frame:CGRect(x: 5, y: 10, width: 20, height: 20))
imageView.image = UIImage(named:"arrow.png")
self.addSubview(imageView)
}
}
public func setSecondlabel(title : String){
secondLine.removeFromSuperview()
secondLine.frame = CGRect(x: 50, y: 0, width: 200, height: 40)
secondLine.text = title
secondLine.font = UIFont.boldSystemFont(ofSize: 20)
secondLine.removeFromSuperview()
self.addSubview(secondLine)
}
}
My issue is my view size is not updating on different devices when using
self.bounds.size.width
for the firstLine label as shown in below image its position should be on the custom button right edge
You need to override the layoutSubviews function have the frame of each element examine and update based on updated bounds of the custom view or assign proper layout constraints on each element while adding it.
If you are overriding the UIButton which has already a label and image property, you can use that one as well or create a custom class inherited from UIControl and create required three property as needed. I am adding an example of the custom class with image, title, and detail as shown in the problem.
class CustomButton : UIControl {
let imageView : UIImageView
let titleLabel : UILabel
let detailLabel : UILabel
fileprivate func setup() {
self.detailLabel.textAlignment = .right
self.detailLabel.font = UIFont.systemFont(ofSize: 20)
self.detailLabel.textColor = UIColor.black
self.titleLabel.font = UIFont.boldSystemFont(ofSize: 20)
self.titleLabel.textColor = UIColor.black
self.backgroundColor = UIColor.white
self.addSubview(self.imageView)
self.addSubview(self.titleLabel)
self.addSubview(self.detailLabel)
}
override init(frame: CGRect) {
self.imageView = UIImageView(frame: .zero)
self.titleLabel = UILabel(frame: .zero)
self.detailLabel = UILabel(frame: .zero)
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
self.imageView = UIImageView(frame: .zero)
self.titleLabel = UILabel(frame: .zero)
self.detailLabel = UILabel(frame: .zero)
super.init(coder: aDecoder)
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
self.imageView.frame = CGRect(x: 5.0, y: self.bounds.midY - 10.0, width: 20.0, height: 20.0)
//You can make this width dynamic if you want to calculate width of text using self.detailLabel.text
var width : CGFloat = 200.0
self.titleLabel.frame = CGRect(x: self.imageView.frame.maxX + 5.0, y: self.bounds.minY, width: 200.0, height: self.bounds.height)
//Give the remaining space to the second label
width = self.bounds.width - (self.titleLabel.frame.maxX + 15.0)
self.detailLabel.frame = CGRect(x: self.titleLabel.frame.maxX + 5.0, y: self.bounds.minY, width: width, height: self.bounds.height)
}
}

Custom titleView changes location after push and pop new screen in stack

I'm trying to implement custom titleView for navigation controller with "title" and "description" labels. If I placed this titleView on first VC, it looks good. If I push second VC into navigation stack and pop it, location of the titleView is changed.
titleView's constraints:
titleLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
descriptionLabel.widthAnchor.constraint(equalTo: titleLabel.widthAnchor).isActive = true
titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
descriptionLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 2.0).isActive = true
In viewDidLoad of VC I use follow code to insert titleView:
navigationItem.titleView = BarTitleView()
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
I tried to insert follow lines into viewWillAppear (second VC has different bar buttons and it can be root of problem), but nothing changes
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
How can I fixed this issue?
I have created a Title and Subtitle in the Navigation bar without the need for Interface Builder and constraint modification.
My Function to create the title view looks as follows:
class func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRect(x: 0, y: -8, width: 0, height: 0))
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRect(x: 0, y: 12, width: 0, height: 0))
subtitleLabel.backgroundColor = UIColor.clear
subtitleLabel.textColor = UIColor.white
subtitleLabel.font = UIFont.systemFont(ofSize: 12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
var titleFrame = titleLabel.frame
titleFrame.size.width = subtitleLabel.frame.size.width
titleLabel.frame = titleFrame
titleLabel.textAlignment = .center
}
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: titleLabel.frame.size.width, height: titleLabel.frame.size.height))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
return titleView
}
Then to use the title view in any view controller I just call this line:
self.navigationItem.titleView = Functions.Views.setTitle(title: "Title String", subtitle: "Subtitle String")

Auto-resized navigationBar title misplaced

I have a UINavigationBar with a title of variable length. To make sure the title fits without being truncated I've implemented the following code in my viewDidLoad():
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
titleLabel.text = "\(petsName)'s Day"
titleLabel.font = UIFont.systemFont(ofSize: 30)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.5
self.navBar.topItem?.titleView = titleLabel
However, because I have a bar button item, the title is being moved over to the left:
Is there any way to implement the code above but keep the text center aligned within the navigation bar?
Please help me to resolve this issue
Try this.. may be worked
var view = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
var label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
label.text = "Joys Day"
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 30)
view.addSubview(label)
navigationItem?.titleView = view
Change titleLabel width to device width and align it to center. Try this:
let deviceWidth = UIScreen.main.bounds.size.width
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: deviceWidth, height: 40))
titleLabel.text = "My Test Title"
titleLabel.font = UIFont.systemFont(ofSize: 20)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.adjustsFontSizeToFitWidth = true
titleLabel.minimumScaleFactor = 0.5
titleLabel.textAlignment = .center
self.navigationItem.titleView = titleLabel
Output:

Resources