Not able to reload UICollectionView on button tap - ios

I have one toggle button. Initially, it will be in off mode. So when I turn on my toggle I need to pass a set of data to collection view. And when its tun off again I need to pass a set of data to collection view.
So here is my code :
#IBAction func cateSelTap(_ sender: Any) {
isChecked = !isChecked
if isChecked {
self.subsetTheCategoryListForClientLogin(isCityLogin: false)
}else {
self.subsetTheCategoryListForClientLogin(isCityLogin: true)
}
}
func subsetTheCategoryListForClientLogin(isCityLogin: Bool) {
let cityType = "city"
print("LOG:CATE1 \(self.categoryarr)")
var objectIds = [Int]()
var subsetArray = NSMutableArray()
for i in 0..<self.categoryarr.count {
let type = (self.categoryarr.object(at:i) as AnyObject).value(forKey: "type") as! String
if isCityLogin {
if type == cityType {
subsetArray.add(self.categoryarr.object(at:i) as AnyObject)
objectIds.append(i)
}
} else {
if type != cityType {
subsetArray.add(self.categoryarr.object(at:i) as AnyObject)
objectIds.append(i)
}
}
}
self.categoryarr.removeAllObjects()
self.categoryarr = subsetArray
print("LOG:CATE2 \(self.categoryarr)")
DispatchQueue.main.async{
self.categorycollection.reloadData()
// self.categorycollection.performSelector(onMainThread: #selector(self.categorycollection.reloadData), with: nil, waitUntilDone: true)
}
}
When I run my app, and when I turn off - my collection view data is not showing exact data..still it is showing previous data. Again when I turn off its fully blank.
Any help on this?

Add a new property like categoryarr, say categoryCollectionViewSource and assign initial data to it. Use categoryCollectionViewSource in collection view delegate methods instead of categoryarr. And in the filter method
func subsetTheCategoryListForClientLogin(isCityLogin: Bool) {
let cityType = "city"
print("LOG:CATE1 \(self.categoryarr)")
var objectIds = [Int]()
var subsetArray = NSMutableArray()
for i in 0..<self.categoryarr.count {
let type = (self.categoryarr.object(at:i) as AnyObject).value(forKey: "type") as! String
if isCityLogin {
if type == cityType {
subsetArray.add(self.categoryarr.object(at:i) as AnyObject)
objectIds.append(i)
}
} else {
if type != cityType {
subsetArray.add(self.categoryarr.object(at:i) as AnyObject)
objectIds.append(i)
}
}
}
//note this line
self.categoryCollectionViewSource.removeAllObjects()
self.categoryCollectionViewSource = subsetArray
print("LOG:CATE2 \(self.categoryarr)")
DispatchQueue.main.async{
self.categorycollection.reloadData()
}
}

#IBAction func cateSelTap(_ sender: Any) {
isChecked = !isChecked
if isChecked {
self.subsetTheCategoryListForClientLogin(isCityLogin: false)
} else {
self.subsetTheCategoryListForClientLogin(isCityLogin: true)
}
}

Related

check the text of the buttons in the array

I have 5 buttons and they are in an array. While text of the buttons unequal to cevapLabel.Text, I want to hide them randomize. how to check all buttons text?
like this;
while allButtonsText != cevapLabel.Text {}
Here is my code:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
let num = Int(arc4random_uniform(5))
let buttons:[UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
while buttons != cevapLabel.text {
buttons[num].isHidden = !buttons[num].isHidden
}
}
in this code its show this error: " Binary operator '!=' cannot be applied to operands of type '[UIButton]' and 'String?' "
---EDITED---
I had to make a few changes in my project.
Here is the code:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
var buttons: [UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
for _ in 1...3 {
let randomNumber = Int(arc4random_uniform(UInt32(buttons.count)))
let button = buttons.remove(at: randomNumber)
button.isHidden = true
}
for button in buttons {
button.isHidden = false
}
}
I tried like this:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
var buttons: [UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
for x in buttons {
if x.titleLabel?.text != cevapLabel.text {
for _ in 1...3 {
let randomNumber = Int(arc4random_uniform(UInt32(buttons.count)))
let button = buttons.remove(at: randomNumber)
button.isHidden = true
}
}
else {
for button in buttons {
button.isHidden = false
}
}
}
}
And i got that error: "Thread 1: Fatal error: Index out of range"
The issue occurs because you're comparing an array of UIButtons with a String.
You can fix your issue by creating a func returning a Bool and calling it in your while statement like so:
#IBAction func eliminateChoiceClicked(_ sender: Any) {
let num = Int(arc4random_uniform(5))
let buttons:[UIButton] = [buttonA,buttonB,buttonC,buttonD,buttonE]
while !isStringContainedInButtons(buttons) {
buttons[num].isHidden = !buttons[num].isHidden
}
}
func isStringContainedInButtons(buttons: [UIButton]) -> Bool {
for (button in buttons) {
if (button.titleLabel?.text == cevapLabel.text) {
return true
}
}
return false
}
I don’t understand the need for the while loop, I would replace it with
if buttons.map($0.title).filter($0 == cevapLabel.text).count == 0 {
buttons[num].isHidden = !buttons[num].isHidden
}
Swift 4
for button in buttons {
if button.title(for: .normal) == cevapLevel.text {
//your code
}
}

I am trying to store random data into a second array

I am trying to store randomly generated data into a second array so that I am able to press a button to go back to it. At the moment I press back and there is nothing there. I think it is due to the items not being correctly stored in the second array. I will provide the code for reference. Any help would be greatly appreciated!
var randomGeneratedQuotes = Array <String>()
var currentlyShown : String?
var randomQuote: String {
let randomNumber = Int(arc4random_uniform(UInt32(myQuotes.count)))
return myQuotes[randomNumber]
}
var previousRandom: String? {
if currentlyShown == randomQuote {
let previous = randomGeneratedQuotes.index(of: currentlyShown!)! - 1
return randomGeneratedQuotes[previous]
}
return randomGeneratedQuotes.last
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var randomQuote: String {
let randomNumber = Int(arc4random_uniform(UInt32(myQuotes.count)))
return myQuotes[randomNumber]
}
func storePrevious() {
if randomGeneratedQuotes.contains(randomQuote) {return}
randomGeneratedQuotes.append(randomQuote)
}
quotesLabel.text = randomQuote
}
//right hand button tapped
#IBAction func RHSButton(_ sender: Any) {
var randomQuote: String {
let randomNumber = Int(arc4random_uniform(UInt32(myQuotes.count)))
return myQuotes[randomNumber]
}
func storePrevious() {
if randomGeneratedQuotes.contains(randomQuote) {return}
randomGeneratedQuotes.append(randomQuote)
}
quotesLabel.text = randomQuote
}
//left hand button tapped
#IBAction func LHSButton(_ sender: Any) {
func pressedBack() {
currentlyShown = previousRandom
}
quotesLabel.text = previousRandom
}

pass data with Button in swift

I try to pass data from my ViewController to TableViewPlace.swiftUse the buttons. When I am choosing button return not some thing
viViewController
class ViewController: UIViewController {
struct Country{
var id :Int
init(id:Int){
self.id = id
}
}
var CountrySelected = [Country]()
var countryArry = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func airAction(sender: AnyObject) {
}
#IBAction func viewPlaceAction(sender: AnyObject) {
getParsePlaceView()
// json viewPlace
performSegueWithIdentifier("viewPlaceSegu", sender: sender)
}
#IBAction func tourAction(sender: AnyObject) {
}
/// Open the page
// parse json
func getParsePlaceView(){
let url = NSURL(string: "http://jsonplaceholder.typicode.com/posts")
NSURLSession.sharedSession().dataTaskWithURL(url!){ [unowned self] (data , repsonse , error) in
if error != nil {
print(error!)
} else {
do {
let posts = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers) as! [[String:AnyObject]]
for post in posts {
if let id = post["userId"] as? Int{
// print(id)
let sets = Country(id: id)
self.CountrySelected.append(sets)
}
}
self.countryArry = posts
print(self.countryArry)// return data and currect
} catch let error as NSError {
print(error)
}
}
}.resume()
print(countryArry) // return nil why??
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
if segue.identifier == "viewPlaceSegu" {
if let secondViewController = segue.destinationViewController as? TableViewPlace {
// set a variable in the second view controller with the String to pass
print(countryArry)
secondViewController.tnt = countryArry
}
}
}
}
when I print(countryArry) return nil why ??
Can someone help me or give me a better solution?
You are creating a Post object with this line :
let countryPlace = Post(userid: post["userId"] as! Int, title: post["title"] as! String)
And you are trying to pass to your tableview this Post object to your tnt variable which is a ViewController class, this is why you've got the first error :
secondViewController.tnt = Country
Then, if you want to add your string country to your mutable array you have to do :
if let title = tnt.title {
Country.append(title)
}

Is there a way to change a UIBarButtonItem immediately in Swift?

I added a "favorite icon" (a heart) in the top Navigation Bar:
var faveMeItem = UIBarButtonItem (title: dua.isFavorite() ? "❤️" : "💔", style: .Plain, target: self, action: "toggleFav")
Is there a way to ensure it is changed (to a broken heart) as soon as it is tapped?
I have to go back to the tableView and come back to the detail, and then I see the updated icon. Tapping on it does the logic, but the heart is not updated. These are the functions in my Dua Class.
func removeFromFavorites() {
//retrieve all favorites
let favoriteDuaIds = NSUserDefaults.standardUserDefaults().objectForKey(Dua.favoriteDuasKey) as! [Int]?
if let favoriteDuaIds = favoriteDuaIds {
//iterate through all Duas and comapre their IDs
let newFavoriteDuaIds = favoriteDuaIds.filter { favoriteDuaId in
return favoriteDuaId != duaId
}
NSUserDefaults.standardUserDefaults().setObject(newFavoriteDuaIds, forKey: Dua.favoriteDuasKey)
}
}
func isFavorite() -> Bool {
//retrieve all favorites
let favoriteDuaIds = NSUserDefaults.standardUserDefaults().objectForKey(Dua.favoriteDuasKey) as! [Int]?
if let favoriteDuaIds = favoriteDuaIds {
//iterate through all Duas and comapre their IDs
for favoriteDuaId in favoriteDuaIds {
print (favoriteDuaId)
if favoriteDuaId == duaId {
return true
}
}
}
return false
}
func toggleFavorite() {
if isFavorite() {
removeFromFavorites()
} else {
addToFavorites()
}
}
class func favorites() -> [Dua] {
let favoriteDuaIds = NSUserDefaults.standardUserDefaults().objectForKey(favoriteDuasKey) as! [Int]?
if let favoriteDuaIds = favoriteDuaIds {
return DuasDataSource.duas.filter { dua in
return favoriteDuaIds.contains(dua.duaId)
}
} else {
return []
}
}
}
func toggleFavorite() {
if isFavorite() {
removeFromFavorites()
} else {
addToFavorites()
}
faveMeItem.title = dua.isFavorite() ? "❤️" : "💔" //Add this
}

how to check all fields in the array contains data

I want to check the array to see if all the fields have a value, and if all the fields have a value, then I want it to do something. My code does work but it is really messy. I'd like to know if there is an easier way of doing this.
#IBAction func testBtn(sender: AnyObject) {
self.textData = arrayCellsTextFields.valueForKey("text") as! [String]
for item in textData {
if item.isEmpty {
print("Missing")
switchKey = true
// alertviewer will go here
break
} else {
switchKey = false
}
}
if switchKey == false {
//navigation here
print("done")
}
}
You can do this with the filterfunction
if textData.filter({$0.isEmpty}).count > 0 {
// there is at least one empty item
} else {
// all items contain data
}
Try this combination of guard and .filter:
#IBAction func testBtn(sender: AnyObject) {
self.textData = arrayCellsTextFields.valueForKey("text") as! [String]
guard textData.count == (textData.filter { !$0.isEmpty }).count else {
print("Missing")
return
}
print("Done")
}

Resources