Swift - Array - Remove a value - ios

It might be a simple question, but I am struggling to find a solution and I am blocked :(
I am working on a CollectionView which displays a list of avatars with their profile pictures. I am trying to add them on a Array when you select it and remove it when you deselect it.
This is my code and I have tried a lots of things but it doesn't work
Function when a cell is selected
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell2 = collectionV.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! SelectFriendCollectionViewCell
let cell5 = self.collectionV.cellForItem(at: indexPath) as? SelectFriendCollectionViewCell
let Friends_avatarname = (cell5?.avatarUsername_Outlet.text! as? String!)!
let Friends_UID = (cell5?.avatarUID_Outlet.text! as? String!)!
let Friend = FriendsSelectArray(avatarUID: (Friends_UID as! String?)!, avatarname: (Friends_avatarname as! String?)!)
self.FriendsSelect.append(Friend)
print ("Friend added :\(Friend.avatarname)")
}
Function if cell deselected
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell2 = collectionV.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! SelectFriendCollectionViewCell
let cell5 = self.collectionV.cellForItem(at: indexPath) as? SelectFriendCollectionViewCell
let Friends_avatarname = (cell5?.avatarUsername_Outlet.text! as? String!)!
let Friends_UID = (cell5?.avatarUID_Outlet.text! as? String!)!
var Friend = FriendsSelectArray(avatarUID: (Friends_UID as! String?)!, avatarname: (Friends_avatarname as! String?)!)
}
The class of the array
class FriendsSelectArray{
var avatarUID: String
var avatarname: String
init( avatarUID: String, avatarname: String){
self.avatarUID = avatarUID
self.avatarname = avatarname
}
func returnPostAsDictionary()->NSDictionary{
let postDictionary: NSDictionary = ["avatarUID": avatarUID,
"avatarname": avatarname]
return postDictionary
}
}
And my starting class of CollectionView
class SelectFriendViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var collectionV: UICollectionView!
var databaseRef: DatabaseReference!
let cellIdentifier = "cell"
var FriendsSelect : [FriendsSelectArray] = []
var selectedCell = [IndexPath]()
It works when I add (When a cell is selected), but I can't manage to remove when you deselect the cell (the specific cell you deselected)
Please, can someone help me ?
A million thanks in advance,

You should compare the IDs of friend being removed from the list with IDs of all friends and remove the one needed from array and reload the collection view.
Please check out below code and comments in code:
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell2 = collectionV.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! SelectFriendCollectionViewCell
let cell5 = self.collectionV.cellForItem(at: indexPath) as? SelectFriendCollectionViewCell
let Friends_avatarname = (cell5?.avatarUsername_Outlet.text! as? String!)!
let Friends_UID = (cell5?.avatarUID_Outlet.text! as? String!)!
var Friend = FriendsSelectArray(avatarUID: (Friends_UID as! String?)!, avatarname: (Friends_avatarname as! String?)!)
// Pseudocode, remove friend from array logic.
// Compare avatarUID of friend being removed and friends in the list.
for x in (0..<FriendsSelect.count).reversed() {
if(FriendsSelect[x].avatarUID == Friend.avatarUID) {
FriendsSelect.remove(at: x)
break
}
}
// TODO: Reload array
}

Set a property in the model so that it can tell you at any instant of time whether it is selected or not. example:
class FriendsSelectArray{
var avatarUID: String
var avatarname: String
var isSeleted: Bool = false
init( avatarUID: String, avatarname: String){
self.avatarUID = avatarUID
self.avatarname = avatarname
}
func returnPostAsDictionary()->NSDictionary{
let postDictionary: NSDictionary = ["avatarUID": avatarUID,
"avatarname": avatarname]
return postDictionary
}
}
then set isSeleted = true in the didselect item and isSelected = false in itemDidDeselect method. After this you can easily filter the selected items from the rest of the items in the array.

Related

Display an array of images in collectionCell inside collectionCell for scrolling. use Class

I use viewController and collectionView inside collectionView. 1st collectionView need to do make a table, 2nd collectionView need to scrolling images.
I can display one image, but in my class Model should load more images (image, image2, image3).
So my class Model:
class Model {
var image: String
var image2: String
var image3: String
var images: [String] = []
var images2: [String] = []
var images3: [String] = []
var ref: FIRDatabaseReference!
init(snapshot: FIRDataSnapshot) {
ref = snapshot.ref
let value = snapshot.value as! NSDictionary
let snap = value["hall1"] as? NSDictionary
let snap2 = value["hall2"] as? NSDictionary
let snap3 = value["hall3"] as? NSDictionary
image = snap?["qwerty"] as? String ?? ""
image2 = snap2?["qwerty"] as? String ?? ""
image3 = snap3?["qwerty"] as? String ?? ""
}
}
My viewController:
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
var image: [Model] = []
var ref: FIRDatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference(withPath: "Студии2")
ref.observe(.value, with: { (snapshot) in
var newImage: [Model] = []
for imageSnap in snapshot.children {
let imageObj = Model(snapshot: imageSnap as! FIRDataSnapshot)
newImage.append(imageObj)
}
self.image = newImage
self.collectionView.reloadData()
})
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return image.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell11
cell.vc1 = self
cell.imagess = [image[indexPath.item]]
return cell
}
}
My collectionCell1:
class CollectionViewCell11: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
var imagess: [Model] = []
#IBOutlet weak var collectionView: UICollectionView!
var vc1: ViewController?
override func awakeFromNib() {
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imagess.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell12
cell.imageView.sd_setImage(with: URL(string: imagess[indexPath.item].image))
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if vc1 != nil {
let vc2 = vc1!.storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
vc2.photo = [imagess[indexPath.item]]
let backItem = UIBarButtonItem()
backItem.title = ""
vc1!.navigationItem.backBarButtonItem = backItem
vc1!.navigationController?.pushViewController(vc2, animated: true)
}
}
}
And my collectionCell2:
class CollectionViewCell12: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
}
Use string in collectionCell1 impossible, because class Model have an array images for future pass in next viewController.
I'm novice, but i think need use another class Model inside new class. But I could be wrong.
I understand my mistake, my mistake is in collectionCell1 line -
cell.imageView.sd_setImage(with: URL(string: imagess[indexPath.item].image))
But i don't understand what I can do...
it should look like this:
But earlier i use type String in var imagess and now me need use class Model
GitHub Link

Parsing multiple images in swift from JSON

Json has multiple images,
img1
Json has date with multiple images, I want show Date and first image of that Date in tableview, working fine.
img2
Note :
when click any cell in tableview, display that Date with all images in collection view, But am parsing only first image of that Date,that image only showing in collection view
how to parse all images from Json and pass to collection view from tableview, and display images into collocation view
img3
this is the code ...
json Code
if errorCode == "0" {
if let Media_list = jsonData["events"] as? [Any] {
self.Mediainfo.removeAll()
for i in 0 ..< Media_list.count {
if let MediaEventData = Media_list[i] as? [String: Any] {
var eventImages = MediaEventData["eventImages"] as? [[String: Any]]
if (eventImages?.count)! > 0 {
let bannerImage = eventImages?[0]["bannerImage"] as? String
print(bannerImage as Any)
self.imageUrl = self.url+"/images/events/" + String(describing: bannerImage!)
self.Mediainfo.append(MediaEvent(
eventId: MediaEventData["eventId"]as?String,
date: MediaEventData["date"]as?String,
eventname: MediaEventData["eventName"]as?String,
bannerImages: self.imageUrl
)
)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Media", for: indexPath)as! MediaCustomTableViewCell
let row = indexPath.row
let media = Mediainfo[row] as MediaEvent
cell.DisplayDate.text = media.date
cell.DisplayName.text = media.eventName
cell.selectionStyle = .none
cell.DisplayImage.downloadImageFrom(link:media.bannerImages, contentMode: UIViewContentMode.scaleAspectFit)
return cell
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let media = Mediainfo[(indexPath.row)] as MediaEvent
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "IMAGEVID") as! UITabBarController
if let viewControllers = tabBarController.viewControllers,
let imageController = viewControllers.first as? ImagesCollectionViewController {
imageController.RecivedData1 = media.bannerImages
}
navigationController?.pushViewController(tabBarController, animated: true)
}
collection view Code :
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImageCollectionViewCell
cell.ImageviewCell.downloadImageFrom(link:nameofImages[indexPath.row], contentMode: UIViewContentMode.scaleAspectFit)
return cell
}
pls help me......!
u can do soemthing like this
let eventImages = MediaEventData["eventImages"] as? [[String: Any]]
if (eventImages?.count)! > 0 {
for i in 0...eventImages.count{
let bannerImage = eventImages?[i]["bannerImage"] as? String
self.imageUrl = self.url+"/images/events/" + String(describing: bannerImage!)
self.Mediainfo.append(bannerImage)
// or like u did u can append to array
self.Mediainfo.append(MediaEvent(
eventId: MediaEventData["eventId"]as?String,
date: MediaEventData["date"]as?String,
eventname: MediaEventData["eventName"]as?String,
bannerImages: self.imageUrl
)
} }
In didselect
let media = Mediainfo[(indexPath.row)] as MediaEvent
imageController.RecivedData1 = media.bannerImages
Your doing like this Means Your are slecting a particular cell and
that index your are passing to NextVC.
if you want to show all images You should pass complete array to
nextvc
You should declare a array of same type Mediainfo array in Next VC
and do like
EX: imageController.array = Mediainfo

How to display dynamically data from Server in CollectionViewCell in TableViewCell with swift3?

I got my json link data from TableViewCell , and then retrieve that data from server and display in collectionView with related TableViewCell data.
How to display this data in swift3? Please, help me.
I got url link (mainThemeList.main_associated_url,main_name) from TableViewCell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let mainThemeList = mainHomeThemeTable[(indexPath as NSIndexPath).row]
let cell = tableView.dequeueReusableCell(withIdentifier: "homecell") as! HomeCategoryRowCell
DispatchQueue.main.async {
cell.categoryTitle.text = mainThemeList.main_name
cell.mainAssociatedURL.text = mainThemeList.main_associated_url
self.prefs.set(mainThemeList.main_name, forKey: "main_name")
cell.categoryTitle.font = UIFont.boldSystemFont(ofSize: 17.0)
cell.collectionView.reloadData()
}
DispatchQueue.main.async {
self.retrieveDataFromServer(associated_url: mainThemeList.main_associated_url,main_name: mainThemeList.main_name)
}
return cell
}
And then data related url link data from Server.
private func retrieveDataFromServe(associated_url : String , main_name: String) {
SwiftLoading().showLoading()
if Reachability().isInternetAvailable() == true {
self.rest.auth(auth: prefs.value(forKey: "access_token") as! String!)
rest.get(url: StringResource().mainURL + associated_url , parma: [ "show_min": "true" ], finished: {(result : NSDictionary, status : Int) -> Void in
self.assetsTable.removeAll()
if(status == 200){
let data = result["data"] as! NSArray
if (data.count>0){
for item in 0...(data.count) - 1 {
let themes : AnyObject = data[item] as AnyObject
let created = themes["created"] as! String
let assets_id = themes["id"] as! Int
let name = themes["name"] as! String
var poster_img_url = themes["poster_image_url"] as! String
let provider_id = themes["provider_id"] as! Int
poster_img_url = StringResource().posterURL + poster_img_url
self.assetsTable.append(AssetsTableItem(main_name: main_name,created: created,assets_id: assets_id, name: name, poster_image_url: poster_img_url,provider_id: provider_id))
}
}
SwiftLoading().hideLoading()
}else{
SwiftLoading().hideLoading()
}
})
}
}
Retrieve data from Server data store in assetsTable.
And then assetsTable data display in CollectionViewCell.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! HomeVideoCell
cell.movieTitle.text = list.name
cell.imageView.image = list.image
return cell
}
My problem is collectionViewCell data are duplicate with previous assetsTable data and didn't show correct data in CollectionView.
My tableViewCell show (Action, Drama) label and My CollectionViewCell show movies Name and Movie Image. I retrieve data for CollectionViewCell from server but CollectionViewCell didn't display related data.
in HomeVideoCell Subclass clean up data in prepareforreuse
override func prepareForReuse() {
super.prepareForReuse()
self.movieTitle.text = ""
self.imageView.image = nil
}

Reload Collection View in a Collection View Cell through delegation

I have a controller (A) with a Collection View that features 2 cell classes. One of them (B) contains another Collection View. After doing some research, I still cannot figure out how to update the cells in (B) from (A) or elsewhere to get what I want.
Issues
(B) does not reload properly when its button is pressed: the cell with whom the button was tied is still visible even though it is deleted from the userFriendRequests array in (A) in its delegate method. As a bonus I get a crash when I scroll to a new cell in (B) stating that "index is out of range" on the line cell.user = userFriendRequests[indexPath.row].
What I Have
Controller (A)
protocol UserFriendRequestsDelegate: class {
func didPressConfirmFriendButton(_ friendId: String?)
}
/...
fileprivate var userFriendRequests = [User]()
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if userFriendRequests.isEmpty == false {
switch indexPath.section {
case 0:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: friendRequestCellId, for: indexPath) as! UserFriendRequests
cell.userFriendRequests = userFriendRequests
cell.delegate = self
return cell
case 1:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserFriendCell
let user = users[indexPath.row]
cell.user = user
return cell
default:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! UserFriendCell
return cell
}
}
/...
extension AddFriendsController: UserFriendRequestsDelegate {
internal func didPressConfirmFriendButton(_ friendId: String?) {
guard let uid = FIRAuth.auth()?.currentUser?.uid, let friendId = friendId else {
return
}
let userRef = FIRDatabase.database().reference().child("users_friends").child(uid).child(friendId)
let friendRef = FIRDatabase.database().reference().child("users_friends").child(friendId).child(uid)
let value = ["status": "friend"]
userRef.updateChildValues(value) { (error, ref) in
if error != nil {
return
}
friendRef.updateChildValues(value, withCompletionBlock: { (error, ref) in
if error != nil {
return
}
self.setUpRequestsStatusesToConfirmed(uid, friendId: friendId)
DispatchQueue.main.async(execute: {
let index = self.currentUserFriendRequests.index(of: friendId)
self.currentUserFriendRequests.remove(at: index!)
for user in self.userFriendRequests {
if user.id == friendId {
self.userFriendRequests.remove(at: self.userFriendRequests.index(of: user)!)
}
}
self.attemptReloadOfCollectionView()
})
})
}
}
PS: self.attemptReloadOfCollectionView() is a func that simply invalidates a timer, sets it to 0.1 sec and then calls reloadData() on (A)'s Collection View.
CollectionViewCell (B)
weak var delegate: UserFriendRequestsDelegate?
var userFriendRequests = [User]()
/...
#objc fileprivate func confirmFriendButtonPressed(_ sender: UIButton) {
delegate?.didPressConfirmFriendButton(friendId)
}
/...
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userFriendRequests.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: friendRequestCellId, for: indexPath) as! FriendRequestCell
cell.user = userFriendRequests[indexPath.row]
return cell
}
/...
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard let firstName = userFriendRequests[indexPath.row].first_name, let lastName = userFriendRequests[indexPath.row].last_name, let id = userFriendRequests[indexPath.row].id else {
return
}
nameLabel.text = firstName + " " + lastName
friendId = id
confirmButton.addTarget(self, action: #selector(confirmFriendButtonPressed(_:)), for: .touchUpInside)
}
What I want to achieve
Update (B) when a User is removed from the userFriendRequests array in (A), this User being identified by his id passed by (B) through delegation.
Any good soul that might have an idea on how to tackle this issue ?
Thanks in advance for your help !

Swift 2 passing data through segue from UIcollectionview (indexpath.row)

I'm trying to pass data (value of dict["IDD"] ) via segue.
(XCODE 7.2)
Here my code:
var arrRes = [[String:AnyObject]]()
var dict = [:]
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("imageCell", forIndexPath: indexPath) as! collectionViewCell
var dict = arrRes[indexPath.row]
let newPrice = dict["price"]!.stringByReplacingOccurrencesOfString(".", withString: ",")
cell.lblPrice.text = "€\(newPrice)"
cell.lblTitle.text = dict["title"] as? String
cell.lblBrand.text = dict["brand"] as? String
cell.lblIDD.text = dict["IDD"] as? String
cell.imageView!.image = UIImage(named: "loading.gif") //set placeholder image first.
dispatch_async(dispatch_get_main_queue()) {
cell.imageView!.downloadImageFrom(link: dict["image"] as! String, contentMode: UIViewContentMode.ScaleAspectFit) //set your image from link array.
}
return cell
}
But I don't kwon how to setup the performseguewithidentifier for segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "homeDetailSegue")
{
let cell = sender as! UICollectionViewCell
let detailView = segue.destinationViewController as! dettaglio
let dict = arrRes[(self.myCollectionView.indexPathForCell(cell))!]
detailView.setnomeOggetto(arrRes["IDD"] as! String)
}
}
I have no problem with tableviews but this is my first time with collectionView
Could please someone help me?
Kind Regards
Thank You very Much
Fabio
I tried the solution for your question and now I got it.Try below the solution.
Before that go to stroyborad click the destinationViewController(here detailViewController)
Then click Identity Inspector of the Right Navigation bar.
Once you click the you can see the Identity under Custom Class
No click Identity then give 'detailsVC' or whatever you want in Storyboard ID.
Now in CollectionViewDelegate Method
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
// handle tap events
print("You selected cell #\(indexPath.item)!")
let detailVC = self.storyboard?.instantiateViewControllerWithIdentifier("detailVC") as! DetailViewController
detailVC.passDataToLabel = String (indexPath.item )
print(detailVC.passDataToLabel)
self.navigationController?.pushViewController(detailVC, animated: true)
}

Resources