How to set first row of table view cell in sidebar different from all other rows - swift

1.8k Views Asked by At

I've created side menu as shown in this..and I want image view only for the first row with full name label so that if anybody clicks on image view of the first row, allow the user to choose an image from the gallery. moreover, all other rows should contain only the text which redirects to another view controller. Please suggest any link or any piece of code get image view only on the first row of side menu with a button to choose an image from gallery. Here is my code

var arrdata = ["Full name", "Home", "Favourite", "Logout"]
var arrimg = [#imageLiteral(resourceName: "hello.png"), #imageLiteral(resourceName: "hello.png"), #imageLiteral(resourceName: "hello.png"), #imageLiteral(resourceName: "hello.png")]

    @IBOutlet var sidebar: UITableView!
    @IBOutlet var sideview: UIView!

        var isSideViewOpen: Bool = false

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return arrdata.count
    }

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
        cell.img.image = arrimg[indexPath.row]
        cell.lbl.text = arrdata[indexPath.row]
        return cell
    }

 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 1
        {
            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
            let HomeViewController = storyBoard.instantiateViewController(withIdentifier: "Home") as! HomeViewController
            self.present(HomeViewController, animated:true, completion:nil)
        }

        if indexPath.row == 3
        {
            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
            let ViewController = storyBoard.instantiateViewController(withIdentifier: "Login") as! ViewController
            self.present(ViewController, animated:true, completion:nil)
        }
    }
   override func viewDidLoad() {
        super.viewDidLoad()
        sideview.isHidden = true
        sidebar.backgroundColor = UIColor.groupTableViewBackground
        isSideViewOpen = false
    }
3

There are 3 best solutions below

4
On BEST ANSWER

First, you will need your custom cell that has an image and the text.

Guide for Custom Cells

After that i would recommend having a list for configuration like

let shouldShowImage = [true, false, false, false, ...]

In your function cellForRowAt you should check if your cell must show the image like

if shouldShowImage[indexPath.row] {

    cell.img.image = arrimg[indexPath.row]
} else {

    cell.img.isHidden = true
}

cell.lbl.text = arrdata[indexPath.row]
2
On

Privacy - Media Library Usage Description
Privacy - Camera Usage Description

1)First add these both keys into your Info.plist file...
2)Then add the button on your image view in your UI.. and give the constraint to them...
1) vertical centre with your image view
2) same hight with your image view.
3) same width with your image view.
4) give leading respect to your image view

3)class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate {

var arrdata = ["Choose Image","Full name", "Home", "Favourite", "Logout"]
var imgVw = UIImageView()
var arrImg = [UIImage(named: "home_bg")]
@IBOutlet var tblVw: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    imgVw.image = UIImage(named: "GalleryIcon")

    tblVw.delegate = self
    tblVw.dataSource = self
    // Do any additional setup after loading the view, typically from a nib.
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return arrdata.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "DemoCell") as! DemoCell
    if indexPath.row == 0 {
        cell.imgvw.image = imgVw.image
        cell.lbl.text = "Choose Image"
    }
    else
    {
        cell.lbl.text = arrdata[indexPath.row]
        cell.imgvw.image = arrImg[0]
    }
    cell.selectionStyle = .none
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.row == 0
    {
        let indexPh = tableView.indexPathForSelectedRow
        let cell = tableView.cellForRow(at: indexPh!) as! DemoCell
        cell.btn.isHidden = false
        cell.btn.addTarget(self, action: #selector(btnChooseImageAction), for: .touchUpInside)
    }
}

@objc private func btnChooseImageAction() {
    let alert = UIAlertController(title: "Choose Image", message: "", preferredStyle: .actionSheet)
    alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (camera) in
        self.openCamera()
    }))
    alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { (gallery) in
        self.openGallery()
    }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    self.present(alert, animated: true, completion: nil)
}

//MARK: -Camera image picker functionality
func openCamera()
{
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera)
    {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.camera
        imagePicker.allowsEditing = false
        self.present(imagePicker, animated: true, completion: nil)
    }
    else
    {
        let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

//MARK: - Gallery image picker functionality:
func openGallery()
{
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
        self.present(imagePicker, animated: true, completion: nil)
    }
    else{
        let alert = UIAlertController(title: "Warningq", message: "You don't have perission to access gallery.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

//MARK:-- ImagePicker delegate
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        imgVw.image = pickedImage
        tblVw.reloadData()
    }
    picker.dismiss(animated: true, completion: nil)
}

}

2
On

Hey i updated the answer please check. Ohkay so if you want two different view you will need to create 2 different UITableViewCells.

One cell will contain your imageView and Label and the other one will contain just a button.

Register both the cell's nib using

tableView.register(UINib(nibName: "your_nib_name", bundle: nil), forCellReuseIdentifier: "your_cell_identifier") method.

Now simply follow this method in cellForRowAt method

if indexPath.row == 0 {
    let cell = tableView.dequeueReusableCell(withIdentifier: "your_image_label_cell", for: indexPath) as! your_image_label_cell_className

    //your code here 
    return cell
} else {
    let cell = tableView.dequeueReusableCell(withIdentifier: "your_button_cell_identifier", for: indexPath) as! your_button_cell_className

   //your code here  
   return cell
}

What i did was i checked that if its the 1st row indexpath.row == 0 it will return the label with image cell, else for all other rows it will return a cell with a button on which you can add tap action event for navigating to different screens.

Similarly, if you want a different tap in the first row you use indexPath.row == 0 in didSelectRowAt method and you are done. Hope this was helpful.