Why UIImageView does not render image in UIView? - swift

I am able to set system image as a button icon and add subviews under views but whatever I try, UIImageView never renders a system image. What am I doing wrong?
override func viewDidLoad() {
super.viewDidLoad()
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
imageView.image = UIImage(named: "pencil")
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
}

You should use UIImage(systemName: "pencil") initializer instead of UIImage(named: "pencil") in order to use images from SFSymbols. You can read more about it here.

Related

UIImage not resizing according to UIImageView size width and height

I am a Swift newbie and I am trying to add an UIImageView on the right of UITextField using Storyboard and #IBInspectable annotation.
However, when I define my UIImageView with specific size and add the UIImage, the UIImage is not resizing according to UIImageView size.
Here's my code:
#IBInspectable var rightImage: UIImage? {
didSet {
guard let image = rightImage else {
return
}
rightViewMode = .always
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
imageView.image = image
imageView.contentMode = .scaleAspectFit
rightView = imageView
and here's the result on the screen:
Big big icon
If you can tell me what is wrong with my code, do not hesitate.
Thanks.
I use constraints based on Matt’s suggestion in the comment, and it's working now:
let constraints = [
imageView.heightAnchor.constraint(equalToConstant: 20),
imageView.widthAnchor.constraint(equalToConstant: 20)
]
NSLayoutConstraint.activate(constraints)

Issue reusing the same UI Image code across multiple view controllers | Swift 5

I have the following function I use to customize the navigation bar across almost all the apps view controllers and table view controllers - instead of replicating the code numerous times I am looking for way to easily call the function on those view controllers needing it.
I have tried wrapping in extension UIViewController { } but run into a selector issue saying the following:
Argument of '#selector' cannot refer to local function
'Tapped(tapGestureRecognizer:)'
Code:
func navBar(){
// Profile Image
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.image = UIImage(url: URL(string: "test.com"))
imageView.contentMode = UIView.ContentMode.scaleAspectFit
imageView.layer.cornerRadius = 20
imageView.layer.masksToBounds = true
containView.addSubview(imageView)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
#objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
print("Profile Tapped")
}
How can this UIImage be seen in the navigation bar across various view controller without needing to rewrite the same code across all.
Lot a way to do it. I'll usually istance and personalize an UIViewController and use it around the whole app.
class baseController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//call your navBar here
navbar()
}
func navBar(){
// Profile Image
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.image = UIImage(url: URL(string: "test.com"))
imageView.contentMode = UIView.ContentMode.scaleAspectFit
imageView.layer.cornerRadius = 20
imageView.layer.masksToBounds = true
containView.addSubview(imageView)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
}
Now instance this class whenever you want and your controller will get your navBar() every time with this
class mineController:baseController {
//your code here...
}

Show multiple images in ViewController in Swift

I have tried the following code to load multiple images in sequence in my ViewController.
import SwiftUI
class ViewController: UIViewController {
var ctrl = MainPageController()
override func viewDidLoad() {
super.viewDidLoad()
Thread.sleep(forTimeInterval: 4.0)
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
var backgroundImageView = UIImageView(frame: CGRect(x:0, y:0, width: width, height: height))
backgroundImageView.image = UIImage(named: "loading")
backgroundImageView.contentMode = .scaleAspectFill
self.view.addSubview(backgroundImageView)
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView.removeFromSuperview()
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView = UIImageView(frame: CGRect(x:0, y:0, width: width, height: height))
backgroundImageView.image = UIImage(named: "loading1")
backgroundImageView.contentMode = .scaleAspectFill
self.view.addSubview(backgroundImageView)
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView.removeFromSuperview()
self.performSegue(withIdentifier: "MainViewSegue", sender: self)
But I see only the second image. I want to load the first image, show it for about 5 seconds, then replace it with the second image, display that for 5 seconds. I have removed the image from the Launch.storyboard. Currently I cannot see any image. The self.performSegue works. How do I fix this problem?
Thanks
Vyasa
It looks like you are creating new image views. If you goal is to simply change the image after 5 seconds you can simplify this code to be something more like:
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = UIImage(named: "Load 1")
imageView.contentMode = .scaleAspectFill
self.view.addSubview(imageView)
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
// the code in this block will only execute after 5 seconds
imageView.image = UIImage(named: "Load 2")
}

How to add a Label for Each Image in the iCarousel View Framework

I have used the iCarousel Framework in my View Controller. But, I am not sure how can I add a label below each image while scrolling in the carousel view. Would appreciate your help! Thanks!
func numberOfItems(in carousel: iCarousel) -> Int {
return 10
}
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/1.4, height: 300))
view.backgroundColor = .red
let imageview = UIImageView(frame: view.bounds)
view.addSubview(imageview)
imageview.contentMode = .scaleToFill
imageview.image = UIImage(named: "Dog_\(index+1)")
return view
}
func carouselDidEndScrollingAnimation() {
if (myCarousel.currentItemIndex == 1) {
dogNameLabel.text = "Brownie!"
}
}
let myCarousel: iCarousel = {
let view = iCarousel()
view.type = .rotary
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(myCarousel)
myCarousel.dataSource = self
myCarousel.frame = CGRect(x: 0, y: 220, width: view.frame.size.width, height: 400)
}
There are too many option. You can create custom view (xib) for reusability. You need to label in contentView above imageView.
But you need to create view like that.
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/1.4, height: 300))
view.backgroundColor = .red
let imageview = UIImageView(frame: view.bounds)
view.addSubview(imageview)
imageview.contentMode = .scaleToFill
imageview.image = UIImage(named: "Dog_\(index+1)")
let label = UILabel()
label.text = "Enter your text"
label.frame = CGRect(x: 0, y: 20, width: view.frame.size.width, height: 30)
//or use constraints
view.addSubview(label)
return view
}

Set image just one time on NavigationBar Swift

I have an app with several ViewControllers, and I have to display an image in the title of the navigation bar, I already have this code to do it.
public func carregarLogoNav() -> Void {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 86, height: 38))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "logo-simples.png")
imageView.image = image
navigationItem.titleView = imageView
}
But I would like to know if it is possible to replicate this image to all other views, without having to paste this code in each one.
Another way would be to just call this function in another ViewController, but it is not working either
anotherViewController().carregarLogoNav()
If you wish to have the same titleView in all of your view controllers then you can put your carregarLogoNav function in an extension and then call it from viewDidLoad of each of your view controllers:
extension UIViewController {
public func setupCarregarLogoNav() {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 86, height: 38))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "logo-simples.png")
imageView.image = image
navigationItem.titleView = imageView
}
}
Then in each view controller:
override func viewDidLoad() {
super.viewDidLoad()
setupCarregarLogoNav()
// any other code
}
This way your setup code is only in once place. It's just called from other places.