How to add subview on custom TitleView's subview - ios

I set custom view to titleView of UINavigationBar.
When I just set the view with frame, it works fine.
However if I add any subview to a view that I set to a title view, it just does not appear.
A view added to titleView
class NavigationBarSearchBar: UIView {
let view: UIView = {
let v = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupSubviews() {
addSubview( view )
[
view.widthAnchor.constraint(equalToConstant: 20),
view.heightAnchor.constraint(equalToConstant: 20),
view.centerYAnchor.constraint(equalTo: centerYAnchor),
view.centerXAnchor.constraint(equalTo: centerXAnchor)
].forEach { $0.isActive = true }
}
}
Declaration on View Controller
private lazy var searchBar: UIView = {
let sb = NavigationBarSearchBar(frame: CGRect(x: 0, y: 0, width: CGFloat.greatestFiniteMagnitude, height: 40))
return sb
}()
Set the custom view to nav bar
navigationItem.titleView = searchBar

lazy var searchBar:UISearchBar = UISearchBar(frame: CGRectMake(0, 0, 200, 20))
searchBar.sizeToFit()
navigationItem.titleView = searchBar

Create a view with Frame and add to navigationItem
var viewTitle = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 30))
viewTitle.backgroundColor = UIColor.red
navigationItem?.titleView = viewTitle

Related

when using CHTWaterfallLayout ,In My collection view cell , subview is not placing properly specially Y co-ordinate.scrolling makes it worse

this is the code where i am configuring the cell.
cell.configure(image: models[indexPath.item].image, tagText: models[indexPath.item].tag, priceIcon: models[indexPath.item].priceIcon, value: models[indexPath.item].price)
and this is my code for cell.
//
// ImageCollectionViewCell.swift
// tr0ve-iOSApp
//
//
//
// ImageCollectionViewCell.swift
// MyCollectionView
//
import UIKit
class ImageCollectionViewCell: UICollectionViewCell {
static let identifier = "ImageCollectionViewCell"
let itemView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(itemView)
contentView.clipsToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
itemView.frame = contentView.bounds
}
override func prepareForReuse() {
super.prepareForReuse()
itemView.subviews.forEach { view in
view.removeFromSuperview()
}
}
func configure (image: UIImage?, tagText: String, priceIcon: UIImage, value: Float){
let imageView = UIImageView(image: image)
let priceTagView = UIView(frame: CGRect(x: 5, y: contentView.frame.size.height-50, width: 60, height: 20))
priceTagView.backgroundColor = .black
let valueLabel = UILabel(frame: CGRect(x: 20, y: 5, width: 35, height: 10))
valueLabel.textColor = .white
valueLabel.text = String(value)
valueLabel.font = UIFont.systemFont(ofSize: 12, weight: .regular)
let priceIconView = UIImageView(frame: CGRect(x: 5, y: 5, width: 10, height: 10))
priceIconView.image = priceIcon
priceTagView.addSubview(priceIconView)
priceTagView.addSubview(valueLabel)
let tag = UILabel(frame: CGRect(x: 100, y: contentView.frame.size.height-50, width: 20, height: 20))
tag.text = tagText
tag.textColor = .white
tag.textAlignment = .center
if tagText == "UC" {
tag.backgroundColor = .green
}
else {
tag.backgroundColor = .blue
}
itemView.addSubview(imageView)
itemView.addSubview(priceTagView)
itemView.addSubview(tag)
}
}
[in this image i want to add subview in cell's bottom, and in tried it using image's frame and by contentView's frame. but it is doing good for some cells and bad for the other ones. and when i scroll everyhing meshes up.1

How can I create dynamic labels using UIStackView

I have 10 UILabels with different sizes, and I want to arrange them in 3 rows, and all rows have leading alignment, and if the last item of each row can't fit in remaining space of parent view, it have to move to the next line. How can I do that by using UIStackview?
You can try to do something like that:
Your ViewController
for item in array {
let someView = VPView(frame: CGRect(x: 0, y: 0, width: 70, height: 20))
someView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(someView)
}
UIView Class:
class VPView: UIView {
let myLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
self.addLabel()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func addLabels() {
//Mark: - Styles
let labelH: CGFloat = 15
let labelW: CGFloat = 70
//MARK: - My Label
self.myLabel.frame = CGRect(x: 0, y: 0, width: labelW, height: labelH)
self.myLabel.backgroundColor = UIColor.blue
self.myLabel.textAlignment = NSTextAlignment.center
self.myLabel.numberOfLines = 0
self.addSubview(self.myLabel)
self.myLabel.translatesAutoresizingMaskIntoConstraints = false
self.myLabel.heightAnchor.constraint(equalToConstant: labelH).isActive = true
self.myLabel.widthAnchor.constraint(equalToConstant: labelW).isActive = true
self.myLabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
self.myLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
}
}

iOS. UINavigationBar with custom height -> vertically center titleView & barButtonItems

I have a custom UINavigationBar:
class NavBar: UINavigationBar {
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
self.barTintColor = .orange
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: 66)
}
}
When I set titleView and/or barButtonItems they are not vertically centered:
class ViewController : UIViewController {
override func viewDidLoad() {
self.viewDidLoad()
self.edgesForExtendedLayout = []
let searchField = UITextField(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
searchField.backgroundColor = .green
self.navigationItem.titleView = searchField
}
}
Result:
How can I vertically center textView & barButtonItems inside UINavigationBar when it's height is not default?
I've tried setting textView's bounds, frame - does not work.
With:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
view.backgroundColor = .green
let searchField = UITextField(frame: CGRect(x: 0, y: -20, width: 100, height: 44))
searchField.backgroundColor = .red
view.addSubview(searchField)
self.navigationItem.titleView = view
I can change the position of the searchField, but it seems like I am doing it wrong.
Can I somehow set UINavigationBar 'padding'/'margin' or textView & barButtonItem offset in the NavBar class?
You're basically hacking UINavigationBar right now that's why I wouldn't expect stable behaviour from it. Apple is discouraging your from doing that. Even in the Apple example of extended UINavBar they just adding another view and make transition between bar and view seamless. You can also try
setTitleVerticalPositionAdjustment(_:for:)
method but I believe it only affects title and not tab bar items. I would use apple solution to avoid unexpected issues or create custom nav bar without subclassing UINavBar.

Dismissing of search bar

I have some problem. I have UITableView and header of tableView is searchController with 1 red view (Inside of this view will be some icon).
After staring of search appears cancel button.
And now I press cancel button and search bar resize to full screen size and red view is disappear.
How to solve this problem?
Here is my headerView class:
lazy var searchController = UISearchController(searchResultsController: nil).then {
//return UISearchController().then {
$0.dimsBackgroundDuringPresentation = false
$0.searchBar.placeholder = "Искать по имени"
$0.searchBar.tintColor = .black
$0.searchBar.searchBarStyle = .minimal
$0.searchBar.backgroundColor = .white
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSFontAttributeName : UIFont.appleSystemRegular(15)], for: .normal)
$0.searchBar.setValue("Отмена", forKey:"_cancelButtonText")
}
lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstrains()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setupViews() {
addSubview(contentView)
addSubview(searchController.searchBar)
}
func setupConstrains() {
searchController.searchBar.frame = CGRect(x: 0, y: 0, width: self.frame.width - 80, height: 44)
contentView.frame = CGRect(x: self.frame.width - 65, y: 0, width: 50, height: 44)
}
Remove searchcontroller and try to search only searchbar delegate.
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
}

How to create custom view programmatically in swift having controls text field, button etc

I am trying to access the MyCustomView from another class using the following code in ViewController.swift ..
var view = MyCustomView(frame: CGRectZero)
.. in the viewDidLoad method. The problem is the view does not get initialized in the simulator.
I have already set class in storyboard for the current ViewController.
class MyCustomView: UIView {
var label: UILabel = UILabel()
var myNames = ["dipen","laxu","anis","aakash","santosh","raaa","ggdds","house"]
override init(){
super.init()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addCustomView()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func addCustomView() {
label.frame = CGRectMake(50, 10, 200, 100)
label.backgroundColor=UIColor.whiteColor()
label.textAlignment = NSTextAlignment.Center
label.text = "test label"
label.hidden=true
self.addSubview(label)
var btn: UIButton = UIButton()
btn.frame=CGRectMake(50, 120, 200, 100)
btn.backgroundColor=UIColor.redColor()
btn.setTitle("button", forState: UIControlState.Normal)
btn.addTarget(self, action: "changeLabel", forControlEvents: UIControlEvents.TouchUpInside)
self.addSubview(btn)
var txtField : UITextField = UITextField()
txtField.frame = CGRectMake(50, 250, 100,50)
txtField.backgroundColor = UIColor.grayColor()
self.addSubview(txtField)
}
The CGRectZero constant is equal to a rectangle at position (0,0) with zero width and height. This is fine to use, and actually preferred, if you use AutoLayout, since AutoLayout will then properly place the view.
But, I expect you do not use AutoLayout. So the most simple solution is to specify the size of the custom view by providing a frame explicitly:
customView = MyCustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
self.view.addSubview(customView)
Note that you also need to use addSubview otherwise your view is not added to the view hierarchy.
Swift 3 / Swift 4 Update:
let screenSize: CGRect = UIScreen.main.bounds
let myView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width - 10, height: 10))
self.view.addSubview(myView)
var customView = UIView()
#IBAction func drawView(_ sender: AnyObject) {
customView.frame = CGRect.init(x: 0, y: 0, width: 100, height: 200)
customView.backgroundColor = UIColor.black //give color to the view
customView.center = self.view.center
self.view.addSubview(customView)
}
let viewDemo = UIView()
viewDemo.frame = CGRect(x: 50, y: 50, width: 50, height: 50)
self.view.addSubview(viewDemo)
view = MyCustomView(frame: CGRectZero)
In this line you are trying to set empty rect for your custom view. That's why you cant see your view in simulator.

Resources