UINavigationBar set background image center swift..? - ios

I'm placing the background image this:
self.navigationController.navigationBar.setBackgroundImage(image, forBarMetrics: .Default)
but, repeat the image. No I want it to be repeated to me and Put it center.. ?

Here's how to fix it using UIAppearance and UIImage API:
// disable image stretching by defining left and top caps.
let navbarImage = image.stretchableImage(withLeftCapWidth: 1, topCapHeight: 1)
UINavigationBar.appearance().setBackgroundImage(navbarImage, for: .default)
Example before:
and after the fix:

Try with below method which worked for me.
var headerview = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 44))
let imgview = UIImageView(frame: CGRect(x: 75, y: 0, width: 150, height: 44))
imgview.image = UIImage(named: "ImageName")
imgview.contentMode = UIViewContentMode.scaleAspectFit
headerview.addSubview(imgview)
self.navigationController?.navigationBar.topItem?.titleView = headerview

Related

UIButton ImageView contentmode doesn't work

I just started an app for iOS in Swift, I'm doing the design programmatically (I mean I'm not using storyboard)
I have a UIButton with an image inside, I would like the image to fill the entire button. Right now it just show the image in my button, but smaller than the button, center in top of the button frame.
My code is :
let buttonLocation = UIButton(frame: CGRect(x: 0, y: 0, width: buttonRoundedSize, height: buttonRoundedSize))
buttonLocation.setImage(UIImage(named: "locate_button"), for: .normal)
buttonLocation.backgroundColor = .white
buttonLocation.layer.cornerRadius = frame.width / 2
buttonLocation.myExtension()
Here are the things I've tried (none of theses worked) :
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.autoresizingMask = .flexibleWidth
self.autoresizingMask = .flexibleHeight
self.imageView?.contentMode = .scaleAspectFill
If I just put the contentMode line it doesn't work either. The imageView doesn't return nil i've checked..
Thanks!
Set the contentMode of buttonLocation's imageView as scaleAspectFill or scaleToFill to cover the entire frame of button.
let buttonLocation = UIButton(frame: CGRect(x: 0, y: 0, width: 200, height: 500))
buttonLocation.setImage(UIImage(named: "image"), for: .normal)
buttonLocation.backgroundColor = .gray
buttonLocation.layer.cornerRadius = buttonLocation.frame.width / 2
buttonLocation.imageView?.contentMode = .scaleAspectFill //Here........
Example:
Try using below code and remove other properties which are being set for this button :
let buttonLocation = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
buttonLocation.setImage(UIImage(named: "cat"), for: .normal)
buttonLocation.backgroundColor = .white
buttonLocation.layer.cornerRadius = 50
buttonLocation.imageView?.contentMode = .scaleAspectFill
buttonLocation.clipsToBounds = true
self.view.addSubview(buttonLocation)
Here make sure that the image which you are setting in the button is larger than the frame of the button. You can change frame and corner radius values in the above code. I just tried with the above code and getting below output.
You can comment if this is not your expected output.
Hope this helps.
Answer on your question: https://stackoverflow.com/a/26263623/3047318
TLDR: set contentMode in viewDidLoad
you need to use setBackgroundImage property instead of setImage.
buttonLocation.setBackgroundImage(UIImage(named: "locate_button"), for: .normal)
Maybe this can help you:
let buttonLocation = UIButton(type: .custom)
buttonLocation.frame = CGRect(x: 0, y: 0, width: buttonRoundedSize, height: buttonRoundedSize)
buttonLocation.setImage(UIImage(named: "locate_button"), for: .normal)
buttonLocation.imageView?.contentMode = .scaleAspectFill
buttonLocation.contentHorizontalAlignment = .fill
buttonLocation.contentVerticalAlignment = .fill
buttonLocation.backgroundColor = .white
buttonLocation.layer.cornerRadius = frame.width / 2
buttonLocation.clipsToBounds = true
You need to add contentHorizontalAlignment and contentVerticalAlignment properties and don't forget set clipsToBounds to true to see the corner raius effect.

Changing frame size of UIImageView in navigation bar not working

I am not able to change the size of my image in the navigation bar for some reason.
Here is my code:
private func setupNavigationBarItems() {
let titleImageView = UIImageView(image: UIImage(named: "radius_image"))
titleImageView.frame = CGRect(x: 0, y: 0, width: 2, height: 2)
titleImageView.contentMode = .scaleAspectFit
navigationItem.titleView = titleImageView
}
It's as if the titleImageView.frame = CGRect(x: 0, y: 0, width: 2, height: 2) line isn't even working.
Haven't found any recent solutions that would help.
UIImageView comes on top of UINavigation Bar title view. In your case you are not changing frame of navigation bar title view.
Using a custom UIView & adding that instance on UINavigationBar item should solve your issue.
let titleView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 2, height: 2)) // Add your frames
let titleImageView = UIImageView(image: UIImage(named: "radius_image")) // Give your image name
titleImageView.frame = titleView.bounds
titleView.addSubview(titleImageView)
self.navigationItem.titleView = titleView

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..?

Why is custom navigation bar button image stretched?

I tried to add a navigation bar button with custom image. However, whatever method I use, the image always appears stretched.
Method 1:
let barbuttonitem = UIBarButtonItem(image: UIImage(named: "apps_small"), style: .plain, target: self, action: nil)
navigationItem.leftBarButtonItem = barbuttonitem
It appears like this:
Method 2:
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "apps_small"), for: .normal)
button.addTarget(self, action: #selector(TeachingRootViewController.appsTouched), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
button.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
It appears like this:
Method 3:
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "apps_small"), for: .normal)
button.setTitle("Button", for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
button.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
button.imageEdgeInsets = .init(top: 5, left: 5, bottom: 5, right: 300)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
navigationItem.leftBarButtonItem?.imageInsets = .init(top: 5, left: 5, bottom: 5, right: 300)
It looks like this:
As you can see the title is gone.
In the UI Hierarchy, it looks like this:
It appears that the button has taken up all spaces in the navigation bar.
However, there is no problem for button with a system item:
Is there anybody who knows the reason for this problem? I think I have run out of ideas.
The above answer is a workaround and not a proper fix.
The correct answer is you should have generate your photos with the correct sizes
asset#1x: 22x22px
asset#2x: 44x44px
asset#3x: 66x66px
Try adding it as a subView instead of setting it as the leftBarButtonItem
var leftButton = UIButton(frame:CGRect(x: 0, y: 0, width: 10, height: 10))
var background = UIImageView(image: UIImage(named: "apps_small"))
background.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
leftButton.addSubview(background)
self.navigationController.navigationBar.addSubview(leftButton)
As per my experience, You have faced this issue because you're added large size images for all resolution 1X, 2X and 3X. You need
to scale it down to a size more appropriate for the navigation bar.
Solution: 1
You need to scale it down to a size more appropriate for the navigation bar. Please have look image sizes for UINavigationBar
asset#1X Size: 24X24
asset#2X Size: 48X48
asset#3X Size: 72X72
Solution: 2
If you want to go with the same images then you need to do below changes in your code.
You just need to add UIImageView inside the UIView then everything
works as expected.
Code:
let containerView = UIControl(frame: CGRect.init(x: 0, y: 0, width: 30, height: 30))
containerView.addTarget(self, action: #selector(handleSearch), for: .touchUpInside)
let imageSearch = UIImageView(frame: CGRect.init(x: 0, y: 0, width: 30, height: 30))
imageSearch.image = UIImage(named: "search")
containerView.addSubview(imageSearch)
let searchBarButtonItem = UIBarButtonItem(customView: containerView)
navigationItem.rightBarButtonItem = searchBarButtonItem
It's all about the Image size that you put inside your UIButton.
If you are using UIButton as a custom view for
UIBarButtonItem(customView: button)
and inside that custom button, you are setting an image. It is better to set the image size to something you need.
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "image")!.resizeImage(newWidth: 25), for: .normal)
And this is a good extension for resizing images in your app. it is using CoreGraphic to resize.
extension UIImage{
//Resize image
func resizeImage(newWidth: CGFloat) -> UIImage {
let originalImage = self
let scale = newWidth / self.size.width
let newHeight = self.size.height * scale
let newImage = self.resizeWithCoreGraphics(to: CGSize(width: newWidth, height: newHeight)) ?? originalImage
return newImage
}
private func resizeWithCoreGraphics(to newSize: CGSize) -> UIImage? {
guard let cgImage = cgImage, let colorSpace = cgImage.colorSpace else { return nil }
let width = Int(newSize.width)
let height = Int(newSize.height)
let bitsPerComponent = cgImage.bitsPerComponent
let bytesPerRow = cgImage.bytesPerRow
let bitmapInfo = cgImage.bitmapInfo
guard let context = CGContext(data: nil, width: width, height: height,
bitsPerComponent: bitsPerComponent,
bytesPerRow: bytesPerRow, space: colorSpace,
bitmapInfo: bitmapInfo.rawValue) else { return nil }
context.interpolationQuality = .high
let rect = CGRect(origin: CGPoint.zero, size: newSize)
context.draw(cgImage, in: rect)
return context.makeImage().flatMap { UIImage(cgImage: $0) }
}
}

How do I put an UIImageView in the center of a tableView

I want my image to be in the center in the x axis, I'm writing this code :
let emptyImage=UIImageView(frame: CGRect(x: (UIScreen.main.bounds.width)/2 ,y: 200 , width: 50, height: 50))
but it doesn't work.
try this
let emptyImage = UIImageView(frame: CGRect(x: UIScreen.main.bounds.width/2 - 50/2, y: 200, width: 50, height : 50)
As you are trying to create image in code. Try adding anchors between imageView and tableview. Find below peace of example code.
let emptyImage = UIImageView(image: UIImage(named: ""))
view1.backgroundColor = UIColor.black // view1 consider this as your tableview
emptyImage.translatesAutoresizingMaskIntoConstraints = false //missed it in first place
self.view1.addSubview(emptyImage)
NSLayoutConstraint.activate([
emptyImage.centerXAnchor.constraint(equalTo: view1.centerXAnchor),
emptyImage.centerYAnchor.constraint(equalTo: view1.centerYAnchor),
emptyImage.heightAnchor.constraint(equalToConstant: 100),
emptyImage.widthAnchor.constraint(equalToConstant: 100)
])
Hope this helps!
Try setting imageView center property to tableView.center:
imageView.center = tableView.center
If you want to show an UIImageView instead of cells, then try this:
let emptyImage=UIImageView(frame:
CGRect(x: 0,
y: 0,
width: self.tableView.bounds.size.width,
height: self.tableView.bounds.size.height))
self.tableView.backgroundView = emptyImage

Resources