var images : [UIImage?] = [nil, nil, nil, nil, nil]
I have image array. I want to replace nil to image by button sender.tag
#IBAction func addImage(_ sender: UIButton) {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1
configuration.filter = .any(of: [.images])
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
self.present(picker, animated: true, completion: nil)
If array[index] is nil, show + image.
But array[index] is a photo, show photo
extension EditViewController: PHPickerViewControllerDelegate {
#available(iOS 14, *)
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
let itemProvider = results.first?.itemProvider
if let itemProvider = itemProvider,
itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in
if let image = object as? UIImage {
DispatchQueue.main.async {
print("image: \(image)")
print("IMAGES ARRAY : \(self.images)")
}
}
}
} else {
//
}
}
}
This code is PHPicerViewControllerDelegate (https://ikyle.me/blog/2020/phpickerviewcontroller)
you can do this with following method
assign tags to your UIButtons and on UIButton action add your image on specific index of array by managing an object
e.g
var selectedIndex or selectedTag // of your UIButton
on Button click update your selectedIndex value with
self.selectedIndex = sender.tag
then in your didFinishPicking method update your images array with selected image on selectedIndex and update your buttons images with following way
images.insert(yourSelectedImage, at: selectedIndex)
self.setImagesForButtons()
now assign your selected image to UIButton using UIButton Outlet
e.g you have five outlets for your five buttons
#IBOutlet weak var yourButtonOutlet1: UIButton!
#IBOutlet weak var yourButtonOutlet2: UIButton!
#IBOutlet weak var yourButtonOutlet3: UIButton!
#IBOutlet weak var yourButtonOutlet4: UIButton!
#IBOutlet weak var yourButtonOutlet5: UIButton!
func setImagesForButtons()
{
if (self.selectedIndex == 0)
{
if (images[selectedIndex] != nil)
{
self.yourButtonOutlet1.setImage(images[selectedIndex], for: .normal)
}
else
{
// set plus icon image to your button
}
}
else if (self.selectedIndex == 1)
{
if (images[selectedIndex] != nil)
{
self.yourButtonOutlet2.setImage(images[selectedIndex], for: .normal)
}
else
{
// set plus icon image to your button
}
}
else if (self.selectedIndex == 2)
{
if (images[selectedIndex] != nil)
{
self.yourButtonOutlet3.setImage(images[selectedIndex], for: .normal)
}
else
{
// set plus icon image to your button
}
}
else if (self.selectedIndex == 3)
{
if (images[selectedIndex] != nil)
{
self.yourButtonOutlet4.setImage(images[selectedIndex], for: .normal)
}
else
{
// set plus icon image to your button
}
}
else if (self.selectedIndex == 4)
{
if (images[selectedIndex] != nil)
{
self.yourButtonOutlet5.setImage(images[selectedIndex], for: .normal)
}
else
{
// set plus icon image to your button
}
}
}
You can use in build Image Picker
extension EditProfileViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// localUserData.ProfileImage = info[.originalImage] as? UIImage
self.imgProfile.image = info[.originalImage] as? UIImage
self.dismiss(animated: true, completion: {
let yes = UIAlertAction(title: "Yes", style: .default, handler: { _ in
self.imgProfile.image = self.localUserData.ProfileImage
})
let no = UIAlertAction(title: "No", style: .default, handler: nil)
self.showCustomAlert(alertMsg: ValidationMsg.imageUpload.rawValue, actions: [yes,no])
})
}
}
The correct answer was given, just want to make it shorter.
The every button should have a tag, from 0 to 4.
Then you can create a property in your controller. Let it be selectedIndex. In the addImage you should add the line:
#IBAction func addImage(_ sender: UIButton) {
self.selectedIndex = _sender.tag
....
}
Then in the delegate method after you got an image:
images[selectedIndex] = image
let buttons = [button1, button2, button3, button4, button5]
let selectedButton = buttons[selectedIndex]
if (images[selectedIndex] != nil) {
selectedButton.setImage(images[selectedIndex], for: .normal)
}
else {
selectedButton.setImage(imagePlus, for: .normal)
}
Related
Im trying to get document for each user login to his account , i have two collections in Firestore one called ( firstName ) and the second one called ( lastName ) and i want from user 1 to get ( firstName ) collection only and user number 2 to get ( lastName ) collection only.
i tried with if statement but it doesn't work with me .
import UIKit
import FirebaseFirestore
import Firebase
import FirebaseAuth
class namesTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet var names: UITableView!
var db: Firestore!
var firstName = [String]()
var lastName = [String]()
override func viewDidLoad() {
super.viewDidLoad()
names.register(UINib(nibName: "Order1TableViewCell", bundle: nil) , forCellReuseIdentifier: "order")
names.dataSource = self
names.delegate = self
db = Firestore.firestore()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController1 = storyboard.instantiateViewController(withIdentifier: "login") as? logInViewController else{return}
viewController1.userNameField?.delegate = self
if viewController1.userNameField?.text == “1#1.com" {
loadData1()
}
if viewController1.userNameField?.text == “2#2.com” {
loadData2()
}
func loadData1() {
db.collection("firstName").getDocuments()
{
(querySnapshot, err) in
if let err = err
{
print("Error getting documents: \(err)");
}
else
{
for document in querySnapshot!.documents {
self.firstName.append(document.get("firstname") as? String ?? "")
self.lastName.append(document.get("lastname") as? String ?? "")
}
}
self.names.reloadData()
}
}
func loadData2() {
db.collection("lastName").getDocuments()
{
(querySnapshot, err) in
if let err = err
{
print("Error getting documents: \(err)");
}
else
{
for document in querySnapshot!.documents {
self.firstName.append(document.get("firstname") as? String ?? "")
self.lastName.append(document.get("lastname") as? String ?? "")
}
}
self.names.reloadData()
}
}
}
this is logInViewController code
import UIKit
import Firebase
import FirebaseAuth
class logInViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var userNameField: UITextField!
#IBOutlet var passwordField: UITextField!
#IBOutlet var logInButton: UIButton!
override func viewDidLoad() {
logInButton.layer.cornerRadius = 4.0
super.viewDidLoad()
userNameField.delegate = self
passwordField.delegate = self
// Do any additional setup after loading the view.
}
#IBAction func logInButtonClicked(_ sender: Any) {
Auth.auth().signIn(withEmail: (userNameField.text ?? ""), password: (passwordField.text ?? "")) { (result, error) in
if let _eror = error{
let alert = UIAlertController(title: "Error", message: error!.localizedDescription, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true)
print(_eror.localizedDescription)
}else{
if let _res = result{
print(_res)
}
let VC1 = self.storyboard!.instantiateViewController(withIdentifier: "order1") as! namesTableViewController
self.navigationController!.pushViewController(VC1, animated: true)
}
}
}
}
this is fire store structure
image
Be careful by doing let view1 = firstViewController() you are not grabbing the correct instance of firstViewController but one you just created. User.text therefore won't be set. You need to grab the right instance of it, if you are using storyboard you can do:
let storyboard = UIStoryboard(name: "nameofstoryboard", bundle: nil)
guard let viewController1 = storyboard.instantiateViewController(withIdentifier: "myIdentifier") as? firstViewController else{return} //set VC Identifier in Storyboard identity inspector
Then you can check the User property with if-statement
I want my swift code to copy the object which is a brown view. So the user hits the copy button then the user hits the object they want to copy and then they point to the area where they want to place the object. Basically the gif below is exactly what I am look at I don't know if you would do something like a clone of something like this.
import UIKit;import CoreData
class ViewController: UIViewController {
var addBoxes = [UIImageView]()
let subview = UIImageView()
var currentView: UIView?
var box = UIButton()
var copyButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[box,copyButton].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
box.backgroundColor = .red
box.setTitle("Add", for: .normal)
copyButton.setTitle("Copy", for: .normal)
NSLayoutConstraint.activate([
box.leadingAnchor.constraint(equalTo: copyButton.trailingAnchor),
box.bottomAnchor.constraint(equalTo: view.bottomAnchor),
box.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.04),
box.widthAnchor.constraint(equalTo:view.widthAnchor ,multiplier: 0.5),
copyButton.leadingAnchor.constraint(equalTo: view.leadingAnchor),
copyButton.bottomAnchor.constraint(equalTo: view.bottomAnchor),
copyButton.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.04),
copyButton.widthAnchor.constraint(equalTo:view.widthAnchor ,multiplier: 0.5),
])
copy.addTarget(self, action: #selector(copyBox), for: .touchDown)
box.addTarget(self, action: #selector(addQuarter), for: .touchDown)
copyButton.backgroundColor = .blue
}
override var prefersStatusBarHidden: Bool {
return true
}
#objc func copyBox() {
}
#objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) {
currentView = gesture.view
let draggedView = gesture.view!
view.bringSubviewToFront(draggedView)
let translation = gesture.translation(in: view)
draggedView.center = CGPoint(x: draggedView.center.x + translation.x, y: draggedView.center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}
#objc func addQuarter(){
let subview = UIImageView()
subview.isUserInteractionEnabled = true
addBoxes.append(subview)
view.addSubview(subview)
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
subview.addGestureRecognizer(pan)
subview.frame = CGRect(x: view.bounds.midX , y: view.bounds.midY + CGFloat(100), width: CGFloat(100), height: 100)
subview.backgroundColor = .brown
addBoxes.append(subview)
}
}
Achieve your requirement with code
class ViewController: UIViewController {
var addBoxes = [UIImageView]()
let subview = UIImageView()
var currentView: UIView?
var location: CGPoint = CGPoint.zero
var box = UIButton()
var copyButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[box,copyButton].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
box.backgroundColor = .red
box.setTitle("Add", for: .normal)
copyButton.setTitle("Copy", for: .normal)
NSLayoutConstraint.activate([
box.leadingAnchor.constraint(equalTo: copyButton.trailingAnchor),
box.bottomAnchor.constraint(equalTo: view.bottomAnchor),
box.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.04),
box.widthAnchor.constraint(equalTo:view.widthAnchor ,multiplier: 0.5),
copyButton.leadingAnchor.constraint(equalTo: view.leadingAnchor),
copyButton.bottomAnchor.constraint(equalTo: view.bottomAnchor),
copyButton.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.04),
copyButton.widthAnchor.constraint(equalTo:view.widthAnchor ,multiplier: 0.5),
])
copyButton.addTarget(self, action: #selector(copyBox), for: .touchDown)
box.addTarget(self, action: #selector(addQuarter), for: .touchDown)
copyButton.backgroundColor = .blue
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:))))
}
override var prefersStatusBarHidden: Bool {
return true
}
#objc func copyBox() {
if let copyObject = currentView?.copyView as? UIImageView{
copyObject.center = location
copyObject.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:))))
view.addSubview(copyObject)
}
}
#objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) {
currentView = gesture.view
let draggedView = gesture.view!
view.bringSubviewToFront(draggedView)
let translation = gesture.translation(in: view)
draggedView.center = CGPoint(x: draggedView.center.x + translation.x, y: draggedView.center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}
#objc func handleTapGestured(_ gesture: UITapGestureRecognizer) {
if self.view == gesture.view{
let loc = gesture.location(in: self.view)
location = loc
}
}
#objc func addQuarter(){
let subview = UIImageView()
subview.isUserInteractionEnabled = true
addBoxes.append(subview)
view.addSubview(subview)
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
subview.addGestureRecognizer(pan)
subview.frame = CGRect(x: view.bounds.midX , y: view.bounds.midY + CGFloat(100), width: CGFloat(100), height: 100)
subview.backgroundColor = .brown
addBoxes.append(subview)
}
}
extension UIView{
var copyView : UIView?{
if let archiv = try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false){
if let view = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(archiv) as? UIView{
return view
}
}
return nil
}
}
a way to achieve copy.
You can do it in the Model level.
In your case, to copy View, is to get the View property ( Frame Size, Color ),
then create a new one.
here is the code instruction
model part
// you can add info , in your needs
struct ViewModel{
let color: UIColor
let size: CGSize
}
Logic Part:
add an UITapGestureRecognizer to the base view (add part view)
in copy mode, the view isUserInteractionEnabled false,
in add mode, the view isUserInteractionEnabled true,
var selectModel: ViewModel?
#objc func copyBox() {
// now in the copy mode
}
func selectView(){
// get current model
selectModel = ViewModel(color: yourView.backgroundColor, size: yourView.frame.size)
}
#objc func AddBox() {
// now in the add mode / paste mode
}
func touchToAdd(_ gesture: UITapGestureRecognizer){
// get the tap location,
// the location point is the new view's center
// use the model from `func selectView(){`
// now you got center . frame size 、color, enough to create a new one ( a copy)
}
I have a chat feature within my app. The page loads the existing data as an array called hhmessages. The last message in the conversation was 'Welcome', when I enter new text 'Thank You' and hit enter the table automatically displays 'Welcome' again instead of 'Thank You.' If it exit out of the page and come back it now shows 'Thank You' as the last message. It's working on the backend just the instant update isn't showing the value in the UITableView when entered.
This is for an iPhone app.
UPDATED TO SHOW COMPLETE CODE - Now that reverse has been removed the new entry shows as blank.
import UIKit
import Foundation
extension String {
// Calculeta the hight string Function
func calculateTextFrameRect(
objectsInPlaceHeight: CGFloat,
objectsInPlaceWidth: CGFloat,
fontSize: CGFloat,
fontWeight: CGFloat) -> CGSize
{
let bounding = CGSize(width: UIScreen.main.bounds.width - objectsInPlaceWidth, height: .infinity)
let rect = NSString(string: self).boundingRect(
with: bounding,
options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin),
attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: fontSize, weight: UIFont.Weight(rawValue: fontWeight))],
context: nil)
return CGSize(width: UIScreen.main.bounds.width, height: rect.height + objectsInPlaceHeight )
}
}
// Messages for test
let frame = CGRect(origin: .zero, size: CGSize.init(width: 375, height: 559))
class Message {
let message: String
var incoming: [Int]
let image: UIImage
var avas = UIImage()
init(message: String, image: UIImage, incoming: Int, avas: UIImage) {
self.message = message
self.image = image
self.incoming = [incoming]
self.avas = avas
}
}
class ConversationViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {
//var user = NSDictionary()
var messages = NSDictionary()
//var guest = NSDictionary()
#IBOutlet var senderLbl: UILabel!
#IBOutlet var senderageLbl: UILabel!
#IBOutlet var senderraceLbl: UILabel!
#IBOutlet var sendergenderLbl: UILabel!
#IBOutlet var sendercityLbl: UILabel!
#IBOutlet var senderstateLbl: UILabel!
// #IBOutlet var tableView: UITableView!
var hhmessages = [AnyObject]()
//var messages: [Message] = []
var pictures = [UIImage]()
var avas = [UIImage]()
var avaURL = [String]()
var isLoading = false
var skip = 0
var limit = 50
var images = [UIImage]()
var incoming: [Int] = []
var comments = [String]()
var ids = [String]()
//var isSent: String = ""
var isPictureSelected = false
//var currentUser_ava = [Any]()
#IBOutlet var pictureImg: UIImageView!
#IBOutlet var avaImg: UIImageView!
#IBOutlet var viewprofile_btn: UIButton!
#IBOutlet var imgprofile_btn: UIButton!
#IBOutlet var replyTxt: UITextView!
//var replyTxt:UITextView!
#IBOutlet var replyTxt_height: NSLayoutConstraint!
#IBOutlet var replyTxt_bottom: NSLayoutConstraint!
#IBOutlet var picSelect: UIButton!
#IBOutlet var replyBtn: UIButton!
var puuid = String()
var imageSelected = false
var coolIndicator: UIActivityIndicatorView!
var commentsTextView_bottom_identity = CGFloat()
#IBOutlet var tableView: UITableView!
// Table View here + basic configuration
override func viewDidLoad() {
//self.tabBarController?.tabBar.isHidden = true
super.viewDidLoad()
tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));
// dynamic cell height
tableView.dataSource = self
tableView.delegate = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 200
loadPosts()
replyTxt.layer.cornerRadius = replyTxt.bounds.width / 50
replyTxt.backgroundColor = UIColor.clear
replyTxt.layer.borderColor = UIColor.gray.cgColor
replyTxt.layer.borderWidth = 1.0
let username = messages["sender"] as? String
self.navigationItem.title = username
}
// pre last func
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// remove observers of notification when the viewController is left
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
// exec-d once notification is caught -> KeyboardWillShow
#objc func keyboardWillShow(_ notification: Notification) {
// getting the size of the keyboard
if let keyboard_size = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
// increasing the bottom constraint by the keyboard's height
replyTxt_bottom.constant += keyboard_size.height
}
// updating the layout with animation
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
// exec-d once notification is caught -> KeyboardWillHide
#objc func keyboardWillHide() {
// updating the layout with animation
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//replyTxt().resignFirstResponder()
self.view.endEditing(false)
}
// TABLEVIEW
// Number os cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return hhmessages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let colorSmoothGray = UIColor(red: 229/255, green: 229/255, blue: 234/255, alpha: 1)
let colorBrandBlue = UIColor(red: 148 / 255, green: 33 / 255, blue: 147 / 255, alpha: 1)
let pictureURL = hhmessages[indexPath.row]["uploadpath"] as? String
print("test 1", pictureURL)
// no picture in the post
if pictureURL == nil || pictureURL == "" {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ConversationCell
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
// shortcuts
let hhpost = hhmessages[indexPath.row]
let text = hhpost["messagetext"] as? String
cell.messageLbl.text = text
cell.messageLbl.textAlignment = .right
cell.messageLbl.backgroundColor = colorSmoothGray
cell.messageLbl.textColor = .black
cell.messageLbl.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)
cell.messageLbl.font?.withSize(25)
cell.messageLbl.clipsToBounds = true
cell.messageLbl.sizeToFit()
pictures.append(UIImage())
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "PicCell", for: indexPath) as! PicConversationCell
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
let smimages = hhmessages[indexPath.row]["path"] as? UIImage
cell.smavaImg.image = smimages
for i in 0 ..< self.incoming.count {
// Confiture the constraints for cell
if self.incoming[indexPath.row] == 1 {
// Text
cell.messageLbl.textAlignment = .left
cell.messageLbl.backgroundColor = colorBrandBlue
cell.messageLbl.textColor = .white
cell.messageLbl.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)
cell.messageLbl.font?.withSize(25)
cell.messageLbl.clipsToBounds = true
// Constraints
cell.lefBubbleConstraint.isActive = true
cell.rightBubbleConstraint.isActive = false
if cell.postpictureImg.image == nil {
cell.postpictureImg.backgroundColor = .black
cell.postpictureImg.clipsToBounds = true
}
else {
cell.postpictureImg.backgroundColor = .black
cell.postpictureImg.clipsToBounds = true
}
}
else if self.incoming[indexPath.row] == 0 {
// Text
cell.messageLbl.textAlignment = .right
cell.messageLbl.backgroundColor = colorSmoothGray
cell.messageLbl.textColor = .black
cell.messageLbl.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)
cell.messageLbl.font?.withSize(25)
cell.messageLbl.clipsToBounds = true
// Constraints
cell.lefBubbleConstraint.isActive = false
cell.rightBubbleConstraint.isActive = true
if cell.postpictureImg.image == nil {
cell.postpictureImg.backgroundColor = .black
cell.postpictureImg.clipsToBounds = true
}
else {
cell.postpictureImg.backgroundColor = .black
cell.postpictureImg.clipsToBounds = true
}
}
if cell.lefBubbleConstraint.isActive == true {
cell.lefImageConstraint.isActive = true
cell.rightImageConstraint.isActive = false
} else {
cell.lefImageConstraint.isActive = false
cell.rightImageConstraint.isActive = true
}
let pictureString = hhmessages[indexPath.row]["uploadpath"] as! String
let pictureURL = URL(string: pictureString)!
// if there are still pictures to be loaded
if hhmessages.count != pictures.count {
URLSession(configuration: .default).dataTask(with: pictureURL) { (data, response, error) in
// downloaded
if let image = UIImage(data: data!) {
self.pictures.append(image)
DispatchQueue.main.async {
cell.postpictureImg.image = image
}
}
}.resume()
// cached picture
} else {
DispatchQueue.main.async {
cell.postpictureImg.image = self.pictures[indexPath.row]
}
}
}
return cell
}
}
// pre load func
override func viewDidAppear(_ animated: Bool) {
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
// func of loading posts from server
#objc func loadPosts() {
//isLoading = true
let me = user!["username"] as! String
let meid = user!["id"] as! String
print(meid)
print(me)
//print(username)
let uuid = messages["uuid"] as! String
print(uuid)
// accessing php file via url path
let url = URL(string: "http://localhost/message.php")!
// pass information to php file
let body = "username=\(me)&uuid=\(uuid)&recipient_id=\(meid)"
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = body.data(using: String.Encoding.utf8)
tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));
// launch session
URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
// no error of accessing php file
// error occured
if error != nil {
Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
//self.isLoading = false
return
}
do {
// access data - safe mode
guard let data = data else {
Helper().showAlert(title: "Data Error", message: error!.localizedDescription, in: self)
//self.isLoading = false
return
}
// getting content of $returnArray variable of php file
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
// accessing json data - safe mode
guard let posts = json?["messages"] as? [NSDictionary] else {
//self.isLoading = false
return
}
// assigning all successfully loaded posts to our Class Var - posts (after it got loaded successfully)
self.hhmessages = posts
self.tableView.reloadData()
// scroll to the latest index (latest cell -> bottom)
let indexPath = IndexPath(row: self.hhmessages.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
// self.isLoading = false
} catch {
Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
//self.isLoading = false
return
}
}
}.resume()
}
#IBAction func viewprofile_clicked(_ sender: Any) {
// performSegue(withIdentifier: "guest2", sender: self.guest)
}
#IBAction func imgprofile_clicked(_ sender: Any) {
// performSegue(withIdentifier: "guest2", sender: self.guest)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "guest" {
if let destination = segue.destination as? GuestViewController {
destination.guest = messages
}
}
}
// function sending requset to PHP to uplaod a file
func uploadPost() {
// validating vars before sending to the server
guard let user_id = user?["id"] as? String, let username = user?["username"] as? String, let avaPath = user?["ava"] else {
// converting url string to the valid URL
if let url = URL(string: user?["ava"] as! String) {
// downloading all data from the URL
guard let data = try? Data(contentsOf: url) else {
return
}
// converting donwloaded data to the image
guard let image = UIImage(data: data) else {
return
}
// assigning image to the global var
let currentUser_ava = image
}
return
}
let user_id_int = Int(user_id)!
let messagetext = replyTxt.text.trimmingCharacters(in: .whitespacesAndNewlines)
hhmessages.insert(messagetext as AnyObject, at: hhmessages.endIndex)
let indexPath = IndexPath(row: hhmessages.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));
tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
replyTxt.text = ""
textViewDidChange(replyTxt)
let recipient = messages["username"] as! String
let rid = String(describing: messages["recipient_id"]!)
let uuid = messages["uuid"] as! String
puuid = UUID().uuidString
// prepare request
let url = URL(string: "http://localhost/messagepost.php")!
let body = "sender_id=\(user_id)&sender=\(username)&text=\(messagetext)&recipient_id=\(rid)&recipient=\(recipient)&uuid=\(uuid)&puuid=\(puuid)"
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = body.data(using: .utf8)
// send request
URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
// error happened
if error != nil {
Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
return
}
do {
// converting received data from the server into json format
let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
// safe mode of casting json
guard let parsedJSON = json else {
return
}
// if the status of JSON is 200 - success
if parsedJSON["status"] as! String == "200" {
} else {
Helper().showAlert(title: "400", message: parsedJSON["status"] as! String, in: self)
return
}
// json error
} catch {
Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
return
}
}
}.resume()
}
// exec-d whenever delegated textView has been changed by chars
func textViewDidChange(_ textView: UITextView) {
// declaring new size of the textView. we increase the height
let new_size = textView.sizeThatFits(CGSize.init(width: textView.frame.width, height: CGFloat(MAXFLOAT)))
// assign new size to the textView
textView.frame.size = CGSize.init(width: CGFloat(fmaxf(Float(new_size.width), Float(textView.frame.width))), height: new_size.height)
//UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
//}
}
#IBAction func picSelect_clicked(_ sender: AnyObject) {
// calling picker for selecting iamge
showActionSheet()
}
// this function launches Action Sheet for the photos
func showActionSheet() {
// declaring action sheet
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// declaring camera button
let camera = UIAlertAction(title: "Camera", style: .default) { (action) in
// if camera available on device, than show
if UIImagePickerController.isSourceTypeAvailable(.camera) {
self.showPicker(with: .camera)
}
}
// declaring library button
let library = UIAlertAction(title: "Photo Library", style: .default) { (action) in
// checking availability of photo library
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
self.showPicker(with: .photoLibrary)
}
}
// declaring cancel button
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
// adding buttons to the sheet
sheet.addAction(camera)
sheet.addAction(library)
sheet.addAction(cancel)
// present action sheet to the user finally
self.present(sheet, animated: true, completion: nil)
}
// takes us to the PickerController (Controller that allows us to select picture)
func showPicker(with source: UIImagePickerControllerSourceType) {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
picker.sourceType = source
present(picker, animated: true, completion: nil)
}
// executed whenever the image has been picked via pickerController
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// accessing selected image
let image = info[UIImagePickerControllerEditedImage] as? UIImage
// assigning selected image to pictureImageView
pictureImg.image = image
// cast boolean as TRUE -> Picture Is Selected
isPictureSelected = true
// remove pickerController
pictureImg.image = info[UIImagePickerControllerEditedImage] as? UIImage
self.dismiss(animated: true, completion: nil)
// cast as a true to save image file in server
if pictureImg.image == info[UIImagePickerControllerEditedImage] as? UIImage {
imageSelected = true
}
dismiss(animated: true, completion: nil)
}
// exec when pictureImageView has been tapped
#IBAction func pictureImageView_tapped(_ sender: Any) {
// declaring action sheet
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
// declaring delete button
let delete = UIAlertAction(title: "Delete", style: .destructive) { (action) in
self.pictureImg.image = UIImage()
}
// declaring cancel button
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
// adding buttons to the sheet
sheet.addAction(delete)
sheet.addAction(cancel)
// present action sheet to the user finally
self.present(sheet, animated: true, completion: nil)
}
// custom body of HTTP request to upload image file
func createBodyWithParams(_ parameters: [String: String]?, filePathKey: String?, imageDataKey: Data, boundary: String) -> Data {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
// if file is not selected, it will not upload a file to server, because we did not declare a name file
var filename = ""
if imageSelected == true {
filename = "notes-\(puuid).jpg"
}
let mimetype = "image/jpg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body as Data
}
#IBAction func replyBtn_clicked(_ sender: Any) {
if replyTxt.text.isEmpty == false && replyTxt.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false {
uploadPost()
//tableView.reloadData()
}
}
#objc func keyboardWillChange(notification: NSNotification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curFrame.origin.y
//print("deltaY",deltaY)
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.replyTxt.frame.origin.y+=deltaY // Here You Can Change UIView To UITextField
self.tableView.frame.origin.y+=deltaY // Here You Can Change UIView To UITextField
self.replyBtn.frame.origin.y+=deltaY // Here You Can Change UIView To UITextField
self.picSelect.frame.origin.y+=deltaY // Here You Can Change UIView To UITextField
},completion: nil)
}
func textFieldShouldReturn(_ replyTxt: UITextField) -> Bool {
replyTxt.resignFirstResponder()
return true
}
}
the problem is you are inserting the new text at
let indexPath = IndexPath(row: hhmessages.count - 1, section: 0)
which is the last field of the array.
but in your cellForRow: you have
let text = hhmessages.reversed()[indexPath.row]["messagetext"] as! String
which shows the first field of your array in the last cell of tableView.
I think thats your problem.
Like others have told, you are messing up your order in hhmessages.
Imagine you have messages Welcome, Hello, and you are trying to add Thank Your, your code with more comments:
self.hhmessages.insert(messagetext as AnyObject, at: hhmessages.endIndex) // Thank You is inserted to the end of the array at 3rd position (2)
let indexPath = IndexPath(row: hhmessages.count - 1, section: 0) // ok, let's get index of 3rd row (2)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic) // add new row to the end
tableView.endUpdates()
Then later UIKit asks you to load this new 3rd row at position 2, and you call:
let text = hhmessages.reversed()[indexPath.row]["messagetext"] as! String
The problem is hhmessages.reversed() which reverses your array, and makes Thank you in fact first at position 0, and Welcome the last one at position 2, which will get the text Welcome.
The second problem I see is this line:
let pictureURL = hhmessages[indexPath.row]["uploadpath"] as? String
Here you are getting unreveresed picture url, which at least is very strange.
I am creating individual members in my app, and everything works well. I validate user input, store it in a local array, and then pass the data on to Firebase when I tap 'next'. The app takes me from Step 2 to Step 3. So far so good.
This is what Step 2 looks like if I load the app from scratch: Step 2 Existing Users. The users are pulled from Firebase, and everything is correct.
If I add a new user, everything updates fine. I tap the 'next' button, and Firebase updates with 3 users, all with correct data, and I'm taken to Step 3. All is good still.
But if I tap the 'back' button in the upper left corner of Step 3 (provided by my navigation controller), the app takes me back to Step 2 and now a duplicate entry of the new user shows up in my tableview. Somehow a duplicate user is appended to my array. This only shows up AFTER I click the 'back' button. It doesn't show up in Firebase, but I don't know where it's coming from. I've spent all day trying to figure this out. I'm sure it's a simple problem that I'm overlooking, but I could really use the community's help on this one.
I've looked at this but it didn't help me. I did some tests where I printed out users.count and found that on ViewDidLoad, the count was 0, but on the unwind segue, the count updated to 3 when I added a new user (this was correct, because there were 3 users). But then when I went to Step 3 and tapped the 'back' button to get back to Step 2, Step 2's ViewDidLoad showed a users.count of 4. I have no idea why. I'm completely stumped.
Here is my Step 2 View Controller code in its entirety:
class Step2VC: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var usersTableView: UITableView!
var users = [User]() // create variable called 'users' which is an array of type User (which is a class we created)
var firebaseUser: FIRUser!
var firebaseStorage: FIRStorage!
var ref: FIRDatabaseReference!
var cellStyleForEditing: UITableViewCellEditingStyle = .none
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "users"
usersTableView.dataSource = self
usersTableView.delegate = self
usersTableView.tableFooterView = UIView()
// --------
// Firebase
// --------
firebaseUser = FIRAuth.auth()?.currentUser
firebaseStorage = FIRStorage.storage()
ref = FIRDatabase.database().reference().child("users").child(firebaseUser.uid)
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "edit", style: .plain, target: self, action: #selector(editButtonTapped))
loadExistingUsers() // check to see if there are existing users, and if so, load them into tableview
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
usersTableView.reloadData()
}
// ----------
// Table View
// ----------
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! Step2Cell
cell.myLabel.text = users[indexPath.row].firstName
cell.userImage.image = users[indexPath.row].photo
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
deleteUserConfirmationAlert(tableViewIndexPath: indexPath)
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "EditUser", sender: users[indexPath.row])
}
// ----------
// Navigation
// ----------
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EditUser" {
let nextContoller = segue.destination as! Step2UsersVC
// 'sender' is retrieved from 'didSelectRow' function above
nextContoller.user = sender as? User
nextContoller.navBarTitle = "edit user"
} else if segue.identifier == "AddUser" {
let nextController = segue.destination as! Step2UsersVC
nextController.navBarTitle = "add user"
} else {
print("Segue Initiated:",segue.identifier!)
}
}
#IBAction func unwindToStep2VC(sender: UIStoryboardSegue) {
let sourceVC = sender.source as! Step2UsersVC
let updatedUser = sourceVC.user
if let selectedIndexPath = usersTableView.indexPathForSelectedRow {
// Update an existing user
users[selectedIndexPath.row] = updatedUser!
usersTableView.reloadData()
} else {
// Add a new user
let newIndexPath = IndexPath(row: users.count, section: 0)
users.append(updatedUser!)
usersTableView.insertRows(at: [newIndexPath], with: .automatic)
users.sort(by: {$0.birthday < $1.birthday})
usersTableView.reloadData()
}
}
#IBAction func nextButtonTapped(_ sender: UIButton) {
// check for at least two users
if users.count < 2 {
createAlert(alertTitle: "Users", alertMessage: "You have not created enough users. Please enter in at least two users.")
} else {
// check for at least one parent
if numberOfParents() < 1 {
createAlert(alertTitle: "Users", alertMessage: "You must have at least one parent. Please enter in a parent.")
} else {
confirmationAlert()
}
}
}
// ---------
// Functions
// ---------
// if users exist on Firebase, load them
func loadExistingUsers() {
ref.child("members").observe(.childAdded) { (snapshot: FIRDataSnapshot) in
if let dict = snapshot.value as? [String : Any] {
let userPhotoUrl = dict["profileImageUrl"] as! String
let userFirstName = dict["firstName"] as! String
let userBirthday = dict["birthday"] as! Int
let userPasscode = dict["passcode"] as! Int
let userGender = dict["gender"] as! String
let isUserChildOrParent = dict["childParent"] as! String
let storageRef = FIRStorage.storage().reference(forURL: userPhotoUrl)
storageRef.data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
let pic = UIImage(data: data!)
let user = User(profilePhoto: pic!,
userFirstName: userFirstName,
userBirthday: userBirthday,
userPasscode: userPasscode,
userGender: userGender,
isUserChildOrParent: isUserChildOrParent)
self.users.append(user)
self.users.sort(by: {$0.birthday < $1.birthday})
self.usersTableView.reloadData()
})
}
}
}
func saveUsersToFirebase() {
for user in users {
let storageRef = FIRStorage.storage().reference().child("users").child(firebaseUser.uid).child("members").child(user.firstName)
let profileImg = user.photo
let imageData = UIImageJPEGRepresentation(profileImg, 0.1) // compress photos
storageRef.put(imageData!, metadata: nil, completion: { (metadata, error) in
if error != nil {
return
}
// get Firebase image location and return the URL as a string
let profileImageUrl = (metadata?.downloadURL()?.absoluteString)!
// save user data to Firebase
self.ref?.child("members").child(user.firstName).setValue(["profileImageUrl" : profileImageUrl,
"firstName" : user.firstName,
"birthday" : user.birthday,
"passcode" : user.passcode,
"gender" : user.gender,
"childParent" : user.childParent])
})
}
}
func editButtonTapped() {
if cellStyleForEditing == .none {
cellStyleForEditing = .delete
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "done", style: .done, target: self, action: #selector(editButtonTapped))
} else {
cellStyleForEditing = .none
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "edit", style: .plain, target: self, action: #selector(editButtonTapped))
}
usersTableView.setEditing(cellStyleForEditing != .none, animated: true)
}
func deleteUserConfirmationAlert(tableViewIndexPath: IndexPath) {
// create alert for user to confirm user deletion
let alert = UIAlertController(title: "Delete User", message: "Are you sure you want to delete \(users[tableViewIndexPath.row].firstName)? This cannot be undone.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "okay", style: .default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
// remove user from Firebase
self.ref.child("members").child(self.users[tableViewIndexPath.row].firstName).removeValue()
self.users.remove(at: tableViewIndexPath.row)
self.usersTableView.deleteRows(at: [tableViewIndexPath], with: .fade)
}))
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
self.usersTableView.reloadData()
}))
present(alert, animated: true, completion: nil)
}
func numberOfParents() -> Int {
var parentCount = 0
for user in users {
if user.childParent == "parent" {
parentCount += 1
}
}
return parentCount
}
func createAlert(alertTitle: String, alertMessage: String) {
let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "okay", style: .cancel, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
present(alert, animated: true, completion: nil)
}
func confirmationAlert() {
let alert = UIAlertController(title: "Users", message: "You have entered in \(users.count) users. Are you finished adding family members?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "continue", style: .default, handler: { (action) in
self.saveUsersToFirebase()
self.performSegue(withIdentifier: "GoToStep3", sender: self)
alert.dismiss(animated: true, completion: nil)
}))
alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
}))
present(alert, animated: true, completion: nil)
}
}
Basically I would like my Imagepicker to be able to assign the captured a image to a new row in tableview each time the user input a name and select a image for this name. I encounter at least 2 types of errors for below codes:
1) 'UIImageView' is not a subtype of 'NSString' error being displayed besides "cell.itemImage.image = UIImage(named: selectedImageArray[indexPath.row])"
2) a problem of how to access for example '.contentMode' and '.clipsToBounds' properties of the assigned image (being each in the array to be assigned to the tableview)
Appreciate anyone's help on these~~
Tableview Controller:
import UIKit
class AddPostItemTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITableViewDelegate {
#IBOutlet var titleName: UILabel!
#IBOutlet var tapCamera: UIImageView!
#IBOutlet var tapLibrary: UIImageView!
#IBOutlet weak var itemNameField:UITextField!
#IBOutlet weak var AddPostTableView:UITableView!
var selectedImageArray:[UIImageView!] = []
var selectedItemNameArray:[String!] = []
let tapCameraRec = UITapGestureRecognizer()
let tapLibraryRec = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
tapCameraRec.addTarget(self, action: "tappedCamera")
tapLibraryRec.addTarget(self, action: "tappedLibrary")
tapCamera.addGestureRecognizer(tapCameraRec)
tapLibrary.addGestureRecognizer(tapLibraryRec)
tapLibrary.userInteractionEnabled = true
tapCamera.userInteractionEnabled = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
// Dismiss keyboard on touch
}
func tappedLibrary(){
if itemNameField.text == "" {
let alertController = UIAlertController(title: "Oops", message: "Please key in the name of item first", preferredStyle: .Alert)
let doneAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(doneAction)
self.presentViewController(alertController, animated: true, completion: nil)
return
}
else if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func tappedCamera(){
if itemNameField.text == "" {
let alertController = UIAlertController(title: "Oops", message: "Please key in the name of item first", preferredStyle: .Alert)
let doneAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(doneAction)
self.presentViewController(alertController, animated: true, completion: nil)
return
}
else if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.sourceType = .Camera
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image:UIImageView!, editingInfo: [NSObject : AnyObject]!) {
selectedImageArray.append(image)
selectedImageArray.contentMode = UIViewContentMode.ScaleAspectFill
selectedImageArray.clipsToBounds = true
selectedItemNameArray.append(itemNameField!.text)
dismissViewControllerAnimated(true, completion: nil)
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
// Return the number of rows in the section.
return self.selectedItemNameArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:
NSIndexPath) -> UITableViewCell {
let cellIdentifier = "ItemCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath:
indexPath) as AddPostTableViewCell
// Configure the cell...
cell.itemName.text = selectedItemNameArray[indexPath.row]
cell.itemImage.image = UIImage(named: selectedImageArray[indexPath.row])
return cell
}
Tableview Cell:
import UIKit
class AddPostTableViewCell: UITableViewCell {
#IBOutlet weak var itemName:UILabel!
#IBOutlet weak var itemImage:UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
The first error suggests that your array contains UIImageViews, not names of images. The UIImage(imageNamed: ) accepts name of image as a string. You probably need something like
cell.itemImage.image = selectedImageArray[indexPath.row].image
or if you want to use the UIImage(imageNamed:), use your name array instead.
With regards to the second issue, you can put a dot after the [indexPath.row] to access properties of the stored object at the given index like I did above. Or you can do it in a more readable way:
var myImage = selectedImageArray[indexPath.row]
myImage.someProperty