Can't Change Uiimageview Image in Function (Swift)

Can't change UIImageView image in function (SWIFT)

I think that the problem is the sleep(3), this line block the main thread.
Instead of that use:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
// your code here
}

Apple Reference

Note:

For the most part, use UIKit classes only from your app’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your app’s user interface in any way.

Regards

Why can't I use an image variable to change the image inside of a UI Image

Im not sure if this is the best practice to do but I basically initialized the image I wanted to update and used else if statements to change the image.

import UIKit

class ViewController: UIViewController {

var tapCount : Int = 0

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.addSubview(displayImage)
view.addSubview(displayText)
setupControls()
setupLayout()

}

// Initalized the display image to facebook icon and is updated when next or previous is tapped
private let displayImage: UIImageView = {
let imageName = "facebook_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
imageView.frame = CGRect(x: 0, y: 0, width: 250, height: 250)
return imageView
}()

private let displayText: UITextView = {
let textView = UITextView()
let attributedText = NSMutableAttributedString(string: "Like us on Facebook", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)])
attributedText.append(NSAttributedString(string: "\n\n\nLorem ipsum Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.gray]))
textView.attributedText = attributedText
textView.textAlignment = .center
textView.isEditable = false
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()

private let nextButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("NEXT", for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
return button

}()

@objc func nextButtonTapped() {
tapCount += 1
pageCounter.currentPage += 1
updatePageContent()
print("NEXT \(tapCount)")
}

@objc func backButtonTapped() {
tapCount -= 1
pageCounter.currentPage -= 1
updatePageContent()
print("PREV \(tapCount)")
}

func updatePageContent() {
if tapCount == -1 {
tapCount = 0
} else if tapCount == 0 {
displayImage.image = facebookImage.image
} else if tapCount == 1 {
displayImage.image = twitterImage.image
} else if tapCount == 2 {
displayImage.image = instagramImage.image
} else if tapCount == 3 {
displayImage.image = linkedinImage.image
} else if tapCount == 4 {
displayImage.image = youtubeImage.image
} else if tapCount == 5 {
tapCount = 4
}
}

private let previousButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("PREV", for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
return button

}()

private let pageCounter: UIPageControl = {
let control = UIPageControl()
control.currentPage = 0
control.numberOfPages = 5
control.currentPageIndicatorTintColor = .systemBlue
control.pageIndicatorTintColor = .gray
return control
}()

private let facebookImage: UIImageView = {
let imageName = "facebook_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
return imageView
}()

private let twitterImage: UIImageView = {
let imageName = "twitter_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
return imageView
}()

private let instagramImage: UIImageView = {
let imageName = "instagram_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
return imageView
}()

private let linkedinImage: UIImageView = {
let imageName = "linkedin_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
return imageView
}()

private let youtubeImage: UIImageView = {
let imageName = "youtube_icon.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image)
return imageView
}()

private let facebookText: UITextView = {
let textView = UITextView()
let attributedText = NSMutableAttributedString(string: "Like us on Facebook", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)])
attributedText.append(NSAttributedString(string: "\n\n\nLorem ipsum Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor.gray]))
textView.attributedText = attributedText
textView.textAlignment = .center
textView.isEditable = false
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
return textView
}()

// Sets image and text properties
private func setupLayout() {

//Facebook icon constraints
displayImage.translatesAutoresizingMaskIntoConstraints = false
displayImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
displayImage.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
displayImage.widthAnchor.constraint(equalToConstant: 250).isActive = true
displayImage.heightAnchor.constraint(equalToConstant: 250).isActive = true

//Description contraints
displayText.topAnchor.constraint(equalTo: displayImage.bottomAnchor, constant: 120).isActive = true
displayText.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
displayText.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
displayText.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true

}

// Sets control buttons and counter
private func setupControls() {
view.addSubview(nextButton)
view.addSubview(previousButton)
view.addSubview(pageCounter)

//Next button constraints
nextButton.translatesAutoresizingMaskIntoConstraints = false
nextButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
nextButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
nextButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
nextButton.widthAnchor.constraint(equalToConstant: 120).isActive = true

// Next button constraints
previousButton.translatesAutoresizingMaskIntoConstraints = false
previousButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
previousButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
previousButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
previousButton.widthAnchor.constraint(equalToConstant: 120).isActive = true

// Counter contsraints
pageCounter.translatesAutoresizingMaskIntoConstraints = false
pageCounter.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
pageCounter.centerYAnchor.constraint(equalTo: nextButton.centerYAnchor, constant: 0).isActive = true
pageCounter.leadingAnchor.constraint(equalTo: previousButton.trailingAnchor, constant: 5).isActive = true
pageCounter.trailingAnchor.constraint(equalTo: nextButton.leadingAnchor, constant: 5).isActive = true
}
}

Issue with changing UIImageView Position

Try this:

var offset: CGPoint = CGPoint.zero

override func touchesBegan( . . . ){
offset = touch.location(in: imageView)
offset.x = (imageView.bounds.width / 2) - offset.x
offset.y = (imageView.bounds.height / 2) - offset.y

location = touch.location(in : self.view)
location.x = location.x + offset.x
location.y = location.y + offset.y
. . .
imageView.center = location
. . .
}

override func touchesMoved( . . . ){
location = touch.location(in : self.view)
location.x = location.x + offset.x
location.y = location.y + offset.y
. . .
imageView.center = location
. . .
}

Changing an Image in UIImageView at runtime

Once you have an image view, you don't need to create new ones (every time you hit your button).

You could declare these at the top of your class (with the imageView)

let ofImage = UIImage(named: "OF_farm.png")
let opaImage = UIImage(named: "OPA_farm.png")

and in your case statement just reassign either image to your imageView

    switch farmSegment.selectedSegmentIndex {
case 1:
imageView.image = ofImage
// other things
break
default:
imageView.image = opaImage
// other things
}

In viewDidLoad, after adding the imageView to the scrollView you can add auto layout constraints if they are needed. Just be sure to set this first:

 imageView.translatesAutoresizingMaskIntoConstraints = false

One last note: Don't forget to view your work in the simulator along the way using the 7+ and the SE settings (and others) to ensure that you have something that will work for everyone.

UIImageView within UITableViewCell not changing image

It appears that this is a bug on the iOS 15 simulator on M1 processors. The code functions perfectly on a real device but not on a simulator. I intend to file a radar for this.

imageView.image = UIImage(ciImage: ) won't update a second time

Quick searching ... seems to be either a "bug" or a change...

Changing your generator code to this seems to correct the issue:

func generateQRCode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)

let context = CIContext()

if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)

if let output = filter.outputImage?.transformed(by: transform) {
if let retImg = context.createCGImage(output, from: output.extent) {
return UIImage(cgImage: retImg)
}
}
}
return nil
}

func generateBarcode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)

let context = CIContext()

if let filter = CIFilter(name: "CICode128BarcodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 3, y: 3)

if let output = filter.outputImage?.transformed(by: transform) {
if let retImg = context.createCGImage(output, from: output.extent) {
return UIImage(cgImage: retImg)
}
}
}
return nil
}

ImageView won't update with new image

Try this, it worked for me:

DispatchQueue.main.async {
profilePictureImageView.image = croppedImage
profilePictureImageView.setNeedsDisplay()
}

Essentially you need to specify that you want to update the image via

profilePictureImageView.setNeedsDisplay()


Related Topics



Leave a reply



Submit