how to check all fields in the array contains data - ios

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")
}

Related

Not able to reload UICollectionView on button tap

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)
}
}

Swift how to wait until a value changes

I am writing an application which tests your ability in Classical Greek. And I have a few View Controllers. In the test view controller, I have a huge Begin button, which when pressed initiates a sequence of code, as follows:
#IBAction func test(_ sender: Any) {
beginBtn.isHidden = true
beginBtn.isEnabled = false
answerOne.isHidden = false
answerTwo.isHidden = false
answerThree.isHidden = false
answerFour.isHidden = false
data.currentNumOQue = (data.qCQ + data.qWQ + data.qSQ)
if data.chooseCAlertDataLoaded == false {
data.chooseCharacterQuestionType.addAction(data.chooseCharacterQuestionTypeEngGrk)
data.chooseCharacterQuestionType.addAction(data.chooseCharacterQuestionTypeGrkEng)
data.chooseCAlertDataLoaded = true
} else {
print("not first question")
}
while data.currentQC <= data.qCQ {
present(data.chooseCharacterQuestionType, animated: false, completion: nil)
DispatchQueue.global(qos: .background).async {
while data.chooseCAlertReturnsEngGrk == nil {
}
DispatchQueue.main.sync {
if data.chooseCAlertReturnsEngGrk == true {
//Eng-Grk QUestion
data.chooseCAlertReturnsEngGrk = nil
} else {
//Grk=Eng QUestion
data.chooseCAlertReturnsEngGrk = nil
}
}
}
data.currentQC += 1
data.currentQ += 1
}
data.currentQC = 1
data.currentQW = 1
data.currentQS = 1
}
Can anyone help me in how to wait until the value chooseCAlertReturnsEngGrk is not nil and execute on, but not 'freezing' the UI when doing so?
Override didSet to call some function.. then in that callback function, do whatever you want with the parameter..
class DataSomething {
var chooseCAlertReturnsEngGrkObserver: ((_ newValue: SomeTime?) -> Void)?
var chooseCAlertReturnsEngGrk: SomeType? = nil {
didSet {
chooseCAlertReturnsEngGrkObserver?(chooseCAlertReturnsEngGrk)
}
}
}

How to search for object in Dictionary with SearchBar TableView?

I am using a Dictionary for TableView. I also have a search bar for searching an item in the table.
The data is stored as following:
var namesDic = [String: [Name]]()
And I search through it as:
func updateSearchResults(for searchController: UISearchController) {
if searchController.searchBar.text! == "" {
filteredNames = namesDic
} else {
filteredNames.removeAll()
for persons in namesDic {
let person = persons.value.filter { $0.getName().contains(searchController.searchBar.text!)
}
for boy in person {
filteredNames[String(describing: boy.getName().characters.first!)] = [boy]
}
}
}
self.tableView.reloadData()
}
Problem: I only get one record now when I search for an item.
Is there a better way to implement above?
More lines of code but it is working now. I stored values from dictionary in different variable and filtered those. The filtered values stored in the another variable and then iterate through.
func updateSearchResults(for searchController: UISearchController) {
if searchController.searchBar.text! == "" {
filteredNames = namesDic
} else {
filteredNames.removeAll()
var namesArray = [Name]()
for (_, value) in namesDic {
namesArray += value
}
let namesFilteredArray = namesArray.filter { $0.getName().lowercased().contains(searchController.searchBar.text!.lowercased())
}
for filteredName in namesFilteredArray {
if let letter = filteredName.getName().characters.first {
if filteredNames[String(letter)] != nil {
filteredNames[String(letter)]?.append(filteredName)
} else {
filteredNames[String(letter)] = [filteredName]
}
}
}
}
self.tableView.reloadData()
}

Firebase Retrieving and passing data to variable

ridvankucuk Problem
func getHandleStatus() -> String {
var handle = String()
ref.queryOrderedByChild("status").observeEventType(.ChildAdded, withBlock: { snapshot in
if let status = snapshot.value["status"] as? Int {
if status == 0 {
//print(snapshot.key)
handle = snapshot.key
} else {
print("NO")
}
}
})
return handle
}
When i return "handle", its always empty string. I set the variable "handle = snapshot.key" and when i return, its still empty. Please help.
First of all your method is async and it is not waiting the main thread. So writing return makes no sense. You should do something else.
Define a variable outside of the function such as:
var handle: String? = nil {
didSet{
// You know handle is set now
}
}
And update your getHandleStatus method:
func getHandleStatus(){
var handle = String()
ref.queryOrderedByChild("status").observeEventType(.ChildAdded, withBlock: { snapshot in
if let status = snapshot.value["status"] as? Int {
if status == 0 {
//print(snapshot.key)
self.handle = snapshot.key
} else {
print("NO")
}
}
})
}

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
}

Resources