when i pass static value in bktheme[1] then image is properly set on button.
when i already get value from NSUserDefaults and set as bktheme as under
Defaults = NSUserDefaults.standardUserDefaults()
let shape = Defaults.integerForKey("Chaperone")
print(shape) // output: 1
let str = bkthemes[shape]
keyImageTypeOne = UIImage(named: str) as UIImage?
then image is not set so, how can i set image on button
Please try below code.
If you get image name in str then only below code works.
So i want to suggest you at first print value of str in console.
Defaults = NSUserDefaults.standardUserDefaults()
let shape = Defaults.integerForKey("Chaperone")
print(shape) // output: 1
let str = bkthemes[shape]
yourButton.setImage(UIImage(named: str), forState: UIControlState.Normal)
If you get any issue then give me value of str.
your code is fine just do like
keyImageTypeOne.setImage(UIImage(named: str) as UIImage?, forState: .Normal)
You can do this:
let button:UIButton = UIButton(type: UIButtonType.System)
let image:UIImage = UIImage(named:"nope")!
button.setImage(image, forState: UIControlState.Normal)
Related
I want to add dynamic number of buttons to my VC. So i am looping through my buttons array model and instantiating UIButtons. The problem is with adding target to these buttons. I want to pass in a string to the selector when adding a target, however Xcode compiler doesn't let me do that
Argument of '#selector' does not refer to an '#objc' method, property, or initializer
#objc func didTapOnButton(url: String) { }
let button = UIButton()
button.addTarget(self, action: #selector(didTapOnButton(url: "Random string which is different for every bbutton ")), for: .touchUpInside)
Is there any other solution other than using a custom UIButton
I don't think it is possible to do what you are attempting, you can try like this:
var buttons: [UIButton: String] = []
let button = UIButton()
let urlString = "Random string which is different for every button"
buttons[button] = urlString
button.addTarget(self, action: #selector(didTapOnButton), for: .touchUpInside
#objc func didTapOnButton(sender: UIButton) {
let urlString = self.buttons[sender]
// Do something with my URL
}
As I remember UIButton is hashable...
Another option would be to extend UIButton to hold the information you want:
extension UIButton {
private static var _urlStringComputedProperty = [String: String]()
var urlString String {
get {
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
return Self._urlStringComputedProperty[tmpAddress]
}
set(newValue) {
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
Self._urlStringComputedProperty[tmpAddress] = newValue
}
}
}
let button = UIButton()
button.urlString = "Random string which is different for every button"
button.addTarget(self, action: #selector(didTapOnButton), for: .touchUpInside
#objc func didTapOnButton(sender: UIButton) {
let urlString = sender.urlString
// Do something with my URL
}
So I have a UIButton whose imageView is set to an image using a download URL. For this purpose I use SDWebImage.
Problem is, when I press the delete button, I want the image to completely disappear but I guess it does not work because the image is still being retrieved from cache. How do I solve this?
class ViewController: UIViewController{
var profileButton: UIButton = {
let button = UIButton(type: .system)
return button
}()
var user: User?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(profileButton)
profileButton.addTarget(self, action: #selector(handleDelete), for: .touchUpInside)
self.loadUserPhotos()
}
fileprivate func loadUserPhotos(){
let profileImageUrl = self.user?.profileImageUrl1
if let imageUrl = profileImageUrl, let url = URL(string: imageUrl){
SDWebImageManager.shared().loadImage(with: url, options: .continueInBackground, progress: nil) { (image, _, _, _, _, _) in
self.profileButton.setImage(image?.withRenderingMode(.alwaysOriginal), for: .normal)
}
}
}
#objc func handleDelete(){
self.user?.profileImageUrl1 = ""
self.profileButton.imageView?.image = nil
self.loadUserPhotos()
}
}
To remove the image from UIButton you need to mention the state as well.
self.profileButton.setImage(nil, for: .normal)
You can use :
SDImageCache.shared.removeImage(forKey: url?.description, withCompletion: nil)
I have made a favorite button for my detailViews( i have a master-detail app ) and it saves the button state generally for all cells/DetailsViews...I want if i press index's 3 cell it will save the button state only for there , if i go to index 4 it will save it individually to that row and won't save the same state to all cells.
Favorite Button:
//create a new button
let Favoritebutton: UIButton = UIButton(type: UIButtonType.custom)
//set image for button
Favoritebutton.setImage(UIImage(named: "EmptyHeart.png"), for: .normal)
Favoritebutton.setImage(UIImage(named: "FilledHeart.png"), for: .selected)
//add function for button
Favoritebutton.addTarget(self, action: #selector(self.button), for: .touchUpInside)
//set frame
Favoritebutton.frame = CGRect(x:0,y: 0,width: 35,height: 35)
Favoritebutton.isSelected = UserDefaults.standard.bool(forKey: "isSaved")
let barButton = UIBarButtonItem(customView: Favoritebutton)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
func button(sender: UIButton) {
audioPlayer.play()
let newValue = !sender.isSelected
sender.isSelected = newValue
UserDefaults.standard.set(newValue, forKey: "isSaved")
let tabItem = self.tabBarController?.tabBar.items![3]
sel_val = tabItem?.badgeValue
if(sel_val == nil){
sel_val = "0"
}
let sel_num = Int(sel_val!)
let fav: NSMutableArray = []
fav.add(barImage)
fav.add(barName)
fav.add(streetName)
if sender.isSelected {
tabItem!.badgeValue = String(format: "%d", sel_num! + 1)
favorite.add(fav)
} else {
tabItem!.badgeValue = String(format: "%d", sel_num! - 1)
favorite.remove(fav)
}
}
How can i make the button save state for each indexPath individually like i want?
This will help me finish my favorites feature so your help will be really really appreciated !
Thank you for your help !
What you want is to store array or dictionary, depends on the situation. Here is an example how to store an array How to save NSMutablearray in NSUserDefaults. I suggest to get the values from defaults when app has started and assign it to the value, so you have a local copy. Do not forget to save array back to defaults after every change, or at least when leaving the app.
EDIT:
You want to store Dictionary of bool, so that you can access values for every row. I discourage you to use indexPath, rather you should use an identifier which will be unique for a row.
These will serve as local storage for your app
let favoritesKey = "favorites"
var favorites: [Int: Bool] = [:]
This is how you obtain saved dictionary:
favorites = userDefaults.object(forKey: favoritesKey) as? [Int : Bool] ?? [:]
This is how you change your values:
favorites[index] = true / false
This is how you obtain your values:
let value = favorites[index]
This is how you save values:
let userDefaults = UserDefaults.standard
userDefaults.set(favorites, forKey: favoritesKey)
I'm making an application where it would be nice to be able to compare values inside one array/set.
Let's say I have constants and an array like this:
let blueImage = UIImage(named: "blue")
let redImage = UIImage(named: "red")
button.setImage(blueImage, forState: .Normal)
button2.setImage(redImage, forState: .Normal)
button3.setImage(blueImage, forState: .Normal)
var imageArray:Array<UIImage> = [button.currentImage, button2.currentImage, button3.currentImage]
Is it then possible to check/compare the values in my array and replace the red images with the blue ones.
More specifically is there a way I can check if 2/3 of the images in the array contains a specific image(blueImage), and then replace the last value(redImage) with (blueImage) so that all has the same picture.
I guess you could filter the array with something along these lines:
let filteredArray = filter(imageArray) { $0 == blueImage }
and then run a count.
You could also iterate over your array:
let countBlue = 0
for i in 0..<imageArray.count {
if imageArray[i] == blueImage {
countBlue ++
}
}
To replace an element:
imageArray[2] = blueImage
I need to pick one of these dots. I add them all before viewDidLoad, I need it to pick a random one. My current code returns the error cannot assign to 'openingScreenDynamicDot in 'self'. How is this fixed?
CODE:
let openingScreenDynamicDot = UIImage()
let dotOne = UIImage(named: "dot1.png")
let dotTwo = UIImage(named: "dot2.png")
let dotThree = UIImage(named: "dot3.png")
let dotFour = UIImage(named: "dot4.png")
let dotFive = UIImage(named: "dot5.png")
let dotSix = UIImage(named: "dot6.png")
let dotSeven = UIImage(named: "dot7.png")
let dotEight = UIImage(named: "dot8.png")
let dotNine = UIImage(named: "dot9.png")
let dotTen = UIImage(named: "dot10.png")
let dotEleven = UIImage(named: "dot11.png")
let dotTwelve = UIImage(named: "dot12.png")
let dotThirteen = UIImage(named: "dot13.png")
var imageNumber = arc4random()%13
override func viewDidLoad() {
let theRandomImages = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen]
openingScreenDynamicDot = theRandomImages.objectAtIndex(imageNumber)
}
You declare constants with the let keyword and variables with the var keyword.
So change let openingScreenDynamicDot to var openingScreenDynamicDot
also, a swift native array does not have a objectAtIndex method so..
change
openingScreenDynamicDot = theRandomImages.objectAtIndex(imageNumber)
to
openingScreenDynamicDot = theRandomImages[imageNumber]
You can try this code to generate one of your random "dots".
override func viewDidLoad(){
let openingScreenDynamicDot.image = UIImage(named: "dot\(arc4random_uniform(13) + 1).png")
}
This is called "String Interpolation". For more info, Click here.
I hope this can help you if you are still having problems.