UISearchBar and Two buttons in the Navigation Controller - ios

I am trying to add two buttons and a SearchBar to my navigation controller but the alignment is not correct. I have tried almost everything such as changing the size of SearchBar, UIButton or changing the Y positioning but it didn't work. Any idea how to fix this issue?
I am using iOS 11 and Xcode 9
searchController = UISearchController(searchResultsController: nil)
searchController?.searchBar.frame = CGRect(x: 0, y: 0, width: 200, height: 30)
searchController?.delegate = self
searchController?.searchResultsUpdater = self
let refineButton = UIButton.init(type: UIButtonType.custom)
refineButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
refineButton.setImage(#imageLiteral(resourceName: "settings-button"), for: UIControlState.normal)
refineButton.widthAnchor.constraint(equalToConstant: 30).isActive = true
refineButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
let refineItem = UIBarButtonItem(customView: refineButton)
navigationItem.leftBarButtonItem = refineItem
navigationItem.titleView = searchController?.searchBar
searchController?.searchBar.sizeToFit()

Please check :
override func viewWillLayoutSubviews() {
searchController?.searchBar.frame = CGRect(x: 0, y: 0, width: 300, height: 30)
searchController?.searchBar.sizeToFit()
}

Related

Swift Add UIView with subviews to titleView

I'd like to customize my navigation bar and insert a UIView with two subviews into the title view of the navigation bar.
Unfortunately the subviews aren't displayed.
Do you have any idea why?
let titleContainer = UIView()
titleContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
let searchIcon = UIButton()
searchIcon.setImage(UIImage(named: "search_icon"), for: UIControlState.normal)
searchIcon.layer.frame = CGRect(x: 0, y: (UIScreen.main.bounds.size.height - 28) / 2, width: 28, height: 28)
titleContainer.addSubview(searchIcon)
let titleLabel = UILabel()
titleLabel.frame = CGRect(x: 28, y: UIScreen.main.bounds.size.height, width: UIScreen.main.bounds.size.width-28, height: UIScreen.main.bounds.size.height)
titleLabel.textColor = UIColor(red:255, green:255, blue:255, alpha:1.0)
titleContainer.addSubview(self.titleLabel)
self.navigationItem.titleView = titleContainer
problem and expected solution:
Why did you use height of all the element as UIScreen.main.bounds.size.height? Please try the below code.
P.S. I have changed the color of searchIcon as i didn't have the image and changed the color of text of label and added some text so that it is visible.
let titleContainer = UIView()
titleContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 45)
let searchIcon = UIButton()
//searchIcon.setImage(UIImage(named: "search_icon"), for: UIControlState.normal)
searchIcon.backgroundColor = UIColor.red
searchIcon.layer.frame = CGRect(x: 0, y: 8, width: 28, height: 28)
titleContainer.addSubview(searchIcon)
let titleLabel = UILabel()
titleLabel.frame = CGRect(x: 28, y: 8, width: UIScreen.main.bounds.size.width-28, height: 30)
titleLabel.textColor = UIColor.blue//(red:255, green:255, blue:255, alpha:1.0)
titleContainer.addSubview(titleLabel)
titleLabel.text = "Sample Text"
self.navigationItem.titleView = titleContainer
Here is the screenshot of the above code:
Please change the x,y accordingly as per your requirement.
Have you considered making your let bar = UINavigationBar() programmatically and then add it with: self.view.addSubview(bar)?
So you can push all the "UIBarItems" you want..?

Add buttons to NavigationItem

I try to add button and ImageView on NavigationItem. For this objects I added two functions TouchUp for it. This two objects I added on uiview. UIView I added to UINavigaionItem. I added UIGesture for ImageView and TouchUp action for button. But button and ImageView don't clicking.
The code bellow:
let navView = UIView()
navView.userInteractionEnabled = true
let btn = UIButton(type: UIButtonType.Custom) as UIButton
btn.addTarget(self, action: #selector(ViewController.on_clicked_btn(_:)), forControlEvents: UIControlEvents.TouchUpInside)
btn.frame = CGRectMake(-65, -22, 130, 42)
btn.setTitle("title", forState: .Normal)
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Center
btn.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
btn.titleLabel?.backgroundColor = UIColor.clearColor()
photo.frame = CGRect(x: -110, y: -18, width: 33, height: 33)
photo.layer.borderWidth = 0.5
photo.layer.masksToBounds = false
photo.layer.borderColor = UIColor.grayColor().CGColor
photo.layer.cornerRadius = self.photo_avatar.frame.height/2
photo.clipsToBounds = true
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.on_clicked_photo(_:)))
photo.addGestureRecognizer(tapRecognizer)
photo.userInteractionEnabled = true
navView.addSubview(photo)
navView.addSubview(btn)
self.navigationItem.titleView = navView
Any ideas? Thanks for your help.
It is because you were not initialising UIIview rect in:
let navView = UIView()
Replace this with
let navView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 168, height: 40))
Replace bin frame with:
btn.frame = CGRect(x: 38, y: 0, width: 130, height: 42)
and photo frame
photo.frame = CGRect(x: 0, y: 0, width: 33, height: 33)

Set background color for top safe area only in iOS 11

I'm new to Swift. I have set my top bar programmatically.It works fine for all versions except for iOS version 11.
I want to change the background color of the safe area in iPhone X. Presently I have just added the following code to hide the status bar.
override var prefersStatusBarHidden: Bool {
return true
}
I have created top bar using code:
//Top Bar
let topBar = UIView(frame:CGRect(x: 0,y: 0, width: width, height: 60))
topBar.backgroundColor = UIColor.white
topBar.layer.shadowColor = UIColor.gray.cgColor
topBar.layer.shadowOffset = CGSize(width: 0, height: 3)
topBar.layer.shadowOpacity = 1
topBar.layer.masksToBounds = false
topBar.layer.shadowRadius = 8.0;
//ImageView - Back Button
let backBtn = UIButton(frame:CGRect(x: 25, y: 18, width: 18, height: 34))
let backBtnImage = UIImage(named: "back_button") as UIImage?
backBtn.setImage(backBtnImage, for: .normal)
backBtn.layer.masksToBounds = true
backBtn.addTarget(self,action:#selector(backButtonClicked),
for:.touchUpInside)
//Label - Title
let titleLabel = UILabel(frame:CGRect(x: width * 0.3, y: 13, width: width * 0.55, height: 40))
titleLabel.text = "Favorites"
titleLabel.contentMode = UIViewContentMode.center
//include all in view
topBar.addSubview(titleLabel)
topBar.addSubview(backBtn)
containerView.addSubview(topBar)
Is there a way in which i can do it without using UINavigationBar or setting status bar.
Hi you can also try this one ,
need to add a view with same background which you set in your header view and add to container parent view .
please refer below code
//Top Bar
let safeAreaView = UIView(frame:CGrect(x: 0,y: 0, width: width, height: 40))
safeAreaView.backgroundColor = UIColor.white
self.view.addSubview(safeAreaView)
let topBar = UIView(frame:CGRect(x: 0,y: 0, width: width, height: 60))
topBar.backgroundColor = UIColor.white
topBar.layer.shadowColor = UIColor.gray.cgColor
topBar.layer.shadowOffset = CGSize(width: 0, height: 3)
topBar.layer.shadowOpacity = 1
topBar.layer.masksToBounds = false
topBar.layer.shadowRadius = 8.0;
//ImageView - Back Button
let backBtn = UIButton(frame:CGRect(x: 25, y: 18, width: 18, height: 34))
let backBtnImage = UIImage(named: "back_button") as UIImage?
backBtn.setImage(backBtnImage, for: .normal)
backBtn.layer.masksToBounds = true
backBtn.addTarget(self,action:#selector(backButtonClicked),
for:.touchUpInside)
//Label - Title
let titleLabel = UILabel(frame:CGRect(x: width * 0.3, y: 13, width: width * 0.55, height: 40))
titleLabel.text = "Favorites"
titleLabel.contentMode = UIViewContentMode.center
//include all in view
topBar.addSubview(titleLabel)
topBar.addSubview(backBtn)
containerView.addSubview(topBar)

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")

Swift:How can i set button at the end of View Programmatically

On the button click i have set UIWebView Programmatically.
if(button.tag = 1)
{
let webV:UIWebView = UIWebView(frame: CGRectMake(10, 80, (UIScreen.mainScreen().bounds.width)-20, (UIScreen.mainScreen().bounds.height)/2))
webView.loadHTMLString(html!, baseURL: nil)
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = .greenColor()
button.setTitle("Test Button", forState: .Normal)
button.addTarget(self, action: #selector(buttonAction), forControlEvents: .TouchUpInside)
webView.addSubview(button)
self.view.addSubview(webV)
}
I tried to set the button at the end of webView and i am not able to set. I tried many time still i am in progress. i want to set the button at the end of webView that i have created programmatically.
Use bounds property of the parent view to position your subview.
let bottomMargin = CGFloat(50) //Space between button and bottom of the screen
let buttonSize = CGSize(width: 100, height: 50)
let button = UIButton(frame: CGRect(
x: 0, y: 0, width: buttonSize.width, height: buttonSize.height
))
button.center = CGPoint(x: parentView.bounds.size.width / 2,
y: parentView.bounds.size.height - buttonSize.height / 2 - bottomMargin)
How can I set button at the end of View Programmatically
#IBOutlet weak var bottomView: UIView!
self.bottamView.addSubview(btnTrvalRpt) btnTrvalRpt.translatesAutoresizingMaskIntoConstraints = false btnTrvalRpt.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true btnTrvalRpt.widthAnchor.constraint(equalToConstant: 50).isActive = true btnTrvalRpt.heightAnchor.constraint(equalToConstant: 50).isActive = true btnTrvalRpt.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20).isActive = true –

Resources