-2

I was wondering if there any possible way to create a table view with this style:

enter image description here

I have a dictionary contains title and image values, I need to create a cell one Image-Right / Title-Left and next vice versa. How can achieve something like this?

iOS.Lover
  • 5,923
  • 21
  • 90
  • 162

4 Answers4

0

Yes, you can use a table view to achieve your requirement. you will need to follow the following steps.

Method 1:

  • Create two table view cell XIB's one with left side label and right side image, the second one is with left side image and right side image.
  • Keep same class of both the XIB's you have created but with different identifiers.
  • In your Table view cellForRowAtIndexPath method implement following logic.

    extension ViewController: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return datasourceArray.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if(indexPath.row % 0 == 0) {
                let cell = tableView.dequeueReusableCell(withIdentifier: "RightLabelTableViewCell", for: indexPath) as! CustomTablViewCell
                cell.model = datasourceArray[indexPath.row]
                return cell
            } else {
                let cell = tableView.dequeueReusableCell(withIdentifier: "LeftLabelTableViewCell", for: indexPath) as! CustomTablViewCell
                cell.model = datasourceArray[indexPath.row]
                return cell
             }
           }
         }
    

Note: You can use one class for TableViewCell with a different identifier and design your xib's accordingly.

Method 2:

Flip your table view cell's content view in a such a way that they will swap in your UI.

add the following code into your cellForRowAtIndexPath and also add else part of it because cell for a row may behave weirdly because of dequeing:

 extension UIView {
    /// Flip view horizontally.
    func flipX() {
        transform = CGAffineTransform(scaleX: -transform.a, y: transform.d)
    }
 }

Usage:

cell.contentView.flipX()
cell.yourImage.flipX()
cell.youImageName.flipX()

Don't forget to add else part in cellForRowAt method.

Jarvis The Avenger
  • 2,750
  • 1
  • 19
  • 37
0

You can do it by setAffineTransform in this way:

• build up your tableView with one prototype cell that has an image in left and a label in right
• then do this:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier", for: indexPath) as! YourTableViewCell

    if (indexPath.row % 2 == 0) {
        cell.contentView.layer.setAffineTransform(CGAffineTransform(scaleX: -1, y: 1))
        cell.YourImage.layer.setAffineTransform(CGAffineTransform(scaleX: -1, y: 1))
        cell.YourLabel.layer.setAffineTransform(CGAffineTransform(scaleX: -1, y: 1))
    }

    // do what ever you want ...

    return cell
}

also the best solution is defining 2 prototype cells but in your case this is a tricky and fast way to achieve your goal.

Arash Etemad
  • 1,827
  • 1
  • 13
  • 29
  • I think clean solution is to use 2 different prototype cells. But which one would you recommend performance point of view - A) using setAffineTransform on a common prototype cell or B) 2 different prototype cells? – Yash Tamakuwala Feb 05 '19 at 15:21
-1
  • Create one cell with 2 image and 2 label left and right
  • when you went to left side image that time hide right side image same as in label.

cell

import UIKit

class TestTableViewCell: UITableViewCell {

    @IBOutlet weak var lbl_left: UILabel!
    @IBOutlet weak var lbl_right: UILabel!
    @IBOutlet weak var img_right: UIImageView!
    @IBOutlet weak var img_left: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    func configure_cell(left:Bool)
    {
        if left{
            img_left.isHidden = true
            img_right.isHidden = false
            lbl_left.isHidden = false
            lbl_right.isHidden = true
            self.img_right.image = UIImage(named: "testimg")
        }else{
            img_left.isHidden = false
            img_right.isHidden = true
            lbl_left.isHidden = true
            lbl_right.isHidden = false
            self.img_left.image = UIImage(named: "testimg")
        }
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

ViewController

extension ViewController:UITableViewDataSource,UITableViewDelegate
{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 120
    }
    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return 120
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as? TestTableViewCell
        if (indexPath.row + 1) % 2 == 0 {
            cell?.configure_cell(left: true)
        } else {
            cell?.configure_cell(left: false)
        }

        return cell!
    }
}

enter image description here

Divyesh Gondaliya
  • 884
  • 11
  • 21
-1

There are actually many ways of doing this:

  1. Create 2 cells. Have 2 cells like OddTableViewCell and EvenTableViewCell. You can choose with index path which to use in cellForRow method like:

    extension ViewController: UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return dataArray.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if(indexPath.row%0 == 0) {
                let cell = tableView.dequeueReusableCell(withIdentifier: "EvenTableViewCell", for: indexPath) as! EvenTableViewCell
                cell.model = dataArray[indexPath.row]
                return cell
            } else {
                let cell = tableView.dequeueReusableCell(withIdentifier: "OddTableViewCell", for: indexPath) as! OddTableViewCell
                cell.model = dataArray[indexPath.row]
                return cell
            }
        }
    
    }
    
  2. Have a single cell but duplicate views so you have 2 labels and 2 image views. Then hide them as you need to:

    class MyCell: UITableViewCell {
    
        @IBOutlet private var leftImageView: UIImageView?
        @IBOutlet private var rightImageView: UIImageView?
    
        @IBOutlet private var leftLabel: UILabel?
        @IBOutlet private var rightLabel: UILabel?
    
        var userImage: UIImage? {
            didSet {
                refresh()
            }
        }
        var userName: String? {
            didSet {
                refresh()
            }
        }
        var imageOnLeft: Bool = false {
            didSet {
                refresh()
            }
        }
    
        func refresh() {
            leftImageView?.image = imageOnLeft ? userImage : nil
            leftImageView?.isHidden = !imageOnLeft
            rightImageView?.image = imageOnLeft ? nil : userImage
            rightImageView?.isHidden = imageOnLeft
    
            leftLabel?.text = imageOnLeft ? nil : userName
            leftLabel?.isHidden = imageOnLeft
            rightLabel?.text = imageOnLeft ? userName : nil
            rightLabel?.isHidden = !imageOnLeft
        }
    
    }
    
  3. Have a single cell with stack view. Add a label and image view onto the stack view. You can change order of items in stack view. Some promising answer can be found here. The rest should be pretty similar to the second solution.

(4.) Also you could just use a collection view and have a label cell and an image cell.

Matic Oblak
  • 16,318
  • 3
  • 24
  • 43
  • you can use this from only one cell – Divyesh Gondaliya Feb 05 '19 at 13:00
  • @DivyeshGondaliya As the first sentence says "There are actually many ways of doing this". There are 4 of them explained in my answer. It is hard to tell from your comment but I assume you believe that having 1 cell is somehow better than having 2. That may seem so at least from maintenance perspective but from how table view works and how dequeuing works it is actually most likely better to have 2 dequeue identifiers. – Matic Oblak Feb 05 '19 at 13:05