Setting mask on bar button item with profile picture - ios

I've been struggling for a while with setting up a circular profile picture as a bar button item. The picture comes from a URL using SDWebImage. When I run the app the item appears as a square and all the other right bar button items shift left. Also ran into the same issues when trying to set the object as a UIButton. Does anybody know how I could set a circular mask on the object, and/or why the other bar button items shift left?
#IBOutlet weak var myAvatarButton: UIBarButtonItem! {
didSet {
guard let userImageURL = CurrentUser.shared.imageURL else {
return
}
let avatarImage = UIImageView()
avatarImage.sd_setImage(with: userImageURL, placeholderImage: #imageLiteral(resourceName: "noProfilePhoto"), options: [.refreshCached, .retryFailed, .highPriority]) { [weak self] (image, error, cacheType, imageURL) in
self?.myAvatarButton.image = image?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
}
}
}

In viewDidLoad add myAvatarButton.clipsToBounds = true might work.
But the better approach would be using customView in your UIBarButtonItem.

try this :
...
let avatarImage = UIImageView()
avatarImage.layer.clipsToBounds = true
avatarImage.layer.cornerRadius = avatarImage.frame.width / 2
...
It should set cornerRadius to the exact value to have your view circular.

Since I was getting the image programmatically from a URL this was a little tricky. Turns out the easiest way was to embed a UIImageView inside a View which can be inserted via storyboard into the navigation bar. From there, I created an IBOutlet and changed the corner radius. Also the other bar buttons were no longer shifted over after adjusting the image view's width.

Related

Correct placement of UIImageView in UIBarButtonItem

When attempting to place a UIImageView(UIImage) into a UIBarButtonItem on a UINavigationBar, the image gets placed in the middle of the bar and also has wide fields covering the entire bar. So, doesn't look like a small button on the left.
I've tried various tricks with frame resizing, contentMode settings.
The below code is from my View Controller, which is part of the Navigation Controller stack. Added this image into Assets:
http://pluspng.com/img-png/png-hd-bike-ktm-bike-png-500.png
for testing, named it bike.png and used it in UIImage below.
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "bike")
let imageView = UIImageView(image: image)
imageView.backgroundColor = .blue //for debugging
imageView.contentMode = .scaleAspectFit
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: imageView)
}
The expected result would be to have the image of the motorbike in the left, rather than in the middle. Also, no empty fields to the left and to the right (highlighted in blue for debugging) of the image.
EXPECTED (drew up in Paintbrush):
REALITY:
Ended up resolving as:
imageView.widthAnchor.constraint(equalToConstant: (navigationController?.navigationBar.frame.height)!).isActive = true

NavigationController, keep logo on top without transsition

I have a logo that appear on top of all my UIViewController(controlled by NavigationController).
When I get the transition between UIViewController, the logo also swipe.
What I want: I want to logo(60 pixel height) to always stay. And the swipe transition to appear below the logo.
I've tried this in view delegate, but the logo also swipe :(
let logo = UIImage(named: "logo.png")
let imageView =UIImageView(image:logo)
self.navigationItem.titleView = imageView
Issue: You have the logo swiping when transiting to next VC.
Desired Result: You want to have the logo show up on each VC without the swipe animation. But still have the Swipe animation running for everything below the logo.
What I would do is make a UIScrollView and keep the logo as just a UIImageView.
If you have github repo of this app I can take a look for you.
Subclass the UINavigationController and in the viewDidLoad, configure the logo image view and add it to the navigationBar as a subview. Also, since we're adding it to the navigation bar which is only 44px in height, so a logo with a height of 60px would overflow the bounds.
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let logo = UIImage(named: "logo.png")!
let imageView = UIImageView(image: logo)
let width = logo.size.width * 60 / logo.size.height
imageView.contentMode = .scaleAspectFit
imageView.frame.size = CGSize(width: width, height: 60)
imageView.center = navigationBar.convert(navigationBar.center, to: navigationBar)
navigationBar.addSubview(imageView)
}
}

TabBar icon becoming a rectangle when its state is selected

I use two icons for different states tabBarItem.
My problem is that when tabbar is selected one icon to become a rectangle.
I did the other icons, and they appear well. I was looking for any information not found on this topic. How can I fix it?
My code
override func viewDidLoad() {
super.viewDidLoad()
let triviaMainTableViewController = StoryboardManager.triviaStoryboard.instantiateViewControllerWithIdentifier("TriviaMainTableViewController") as! TriviaMainTableViewController
viewControllers = [triviaMainTableViewController]
tabBarItem.image = UIImage(named: "TriviaTabBarDefault")?.imageWithRenderingMode(.AlwaysOriginal)
tabBarItem.selectedImage = UIImage(named: "TriviaTabBarSelected")
tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
navigationBar.barTintColor = ColorManager.greenColor
}
You need to make sure you have put your icon on a transparent background in order for the selection highlight to work correctly. If the background color of the image isn't transparent it may look fine when it is not selected, but not when it is selected.

Fixed background in a TableView?

Fixed Background image in a TableView ?
Hey guys !
My first question as a Swift nOOb !
I'm trying to set up a fixed image as a background for my Table View. So far, the best option has been to include this in my ViewDidLoad :
let uluru = UIImage(named: "Uluru")
self.view.backgroundColor = UIColor(patternImage: uluru!)
Not so great, right?
Especially because when you're scrolling, the image is tiled. Meaning, it's repeating itself. Does anyone has a solution via the IB or directly into the code to make it fixed ? Something like in CSS ?
I also tried the superview way :
override func viewDidAppear(animated: Bool) {
let uluru = UIImage(named: "Uluru")
let uluruView = UIImageView(image: uluru)
self.view.superview!.insertSubview(uluruView, belowSubview:self.view)
}
But no success at all!
And last but not least :
override func viewDidLoad() {
super.viewDidLoad()
let backgroundImage = UIImageView(frame: UIScreen.mainScreen().bounds)
backgroundImage.image = UIImage(named: "Uluru")
self.view.insertSubview(backgroundImage, atIndex: 0)
}
Thank you all!
Do not use the backgroundColor property for this, and do not add any subviews. The table view is all ready for you to do what you want to do. Like this:
Create an image view (UIImageView) whose image is the desired image.
Make that image view the table view's background view (its backgroundView property).

iOS Swift: Hide and unhide Nav and tool bars

Experts,
I am using following code to hide the tool and nav bars before capturing the screen view. However the image still shows both bars...what I'am I doing wrong?
func generateMeme() ->UIImage {
// Hide toolbar and navbar
self.navigationController?.navigationBarHidden = true
self.navigationController?.toolbarHidden = true
// Render view to an image
UIGraphicsBeginImageContext(self.view.frame.size)
self.view.drawViewHierarchyInRect(self.view.frame,afterScreenUpdates:true)
let memedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// Show toolbar and navbar
self.navigationController?.navigationBarHidden = true
self.navigationController?.toolbarHidden = true
return memedImage
}
Thanks
I'm not doing a screenshot, but I had a similar need - I have a viewController with a UIToolbar at the bottom that I wanted to hide sometimes. I created an outlet to it; and used
#IBOutlet weak var toolBar: UIToolbar!
// later in the code where you don't want it visible anymore
toolBar.isHidden = true
but then there was still space allocated for the toolbar at the bottom of the window; and if the item in the scrollView it was next to was large enough it was really obvious that there was still something there blocking space.
I solved this by selecting the toolbar, and using Embed -> Stack View. Make sure and adjust the constraints of the stackview, setting each top, bottom, left and right to 0. now the same line of code will hide the toolbar, and because it's in a UIStackView, it no longer takes up any space.
You should be able to do the same; hide the toolbar, then snap the image.
Swift 5.1
Hiding the toolbar will be
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setToolbarHidden(true, animated: true
}
I was able to solve the issue by using reference outlet and then using the hidden property. Below is the code:
// Reference outlet for Tool Bar
#IBOutlet weak var toolBar: UIToolbar!
//Reference outlet for Navigation Bar
#IBOutlet weak var navBar: UINavigationBar!
//Generate meme
func generateMeme() ->UIImage {
// Hide toolbar and navbar
self.toolBar.hidden = true
self.navBar.hidden = true
// Render view to an image
UIGraphicsBeginImageContext(view.frame.size)
view.layer.renderInContext(UIGraphicsGetCurrentContext())
let memedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//Show tool and nav bars
self.toolBar.hidden = false
self.navBar.hidden = false
return memedImage
}
Just use this(below) line at specific place in your code after that
your toolBar will be removed permanently:
self.tabBarController?.tabBar.isHidden = true
func getScreenShot() -> UIImage {
UIGraphicsBeginImageContext(view.frame.size)
view.layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
return image
}
This should hide the navigationbar and toolbar. You can find the image in the Photos.
I had been exactly in the same problem and I tried your solution but the wrong was that , I suppose you were trying to address the default navigation controller built in toolbar while you need to address your own toolbar that you created in the story board. I solved the problem as follow
create an outlet from my toolbar to the view controller
#IBOutlet weak var toolbarView: UIToolbar!
make it hidden
self.navigationController?.isNavigationBarHidden = true
self.toolbarView.isHidden = true

Resources