Press ESC to close

Kendi UITableView’imizi Nasıl Oluştururuz?

Merhaba arkadaşlar, bu yazımızda Swift ile nasıl UITableView oluşturabiliriz bundan bahsedeceğiz. Bazı durumlarda UITableView yeterli gelmeyebilir veya kendiniz yönetmek isteyebilirsiniz. Bu durumda UIScrollView ve UIStackView ile yapabiliriz.

Kendi UITableView’imizi oluştururken 3 temel fonksiyonu oluşturacağız. Bunlar;

  • Ekranda kaç adet View gözükecek
  • Hangi View gözükecek
  • View’a tıklandığında ne yapacak

Bunlar için öncesinde bir protokol oluşturacağız. Bu sayede kendi yaptığımız UITableView’i, UIViewController üzerinden delege edebileceğiz.

//
//  CustomStackTableViewDelegate.swift
//  custom-stack-table-view
//
//  Created by Ömer Sezer on 14.01.2023.
//

import UIKit

protocol CustomStackTableViewDelegate {
    func itemPressedAtIndex(index: Int)
    func itemForRowAtIndex(index: Int) -> UIView
    func numberOfItems() -> Int
}

CustomStackTableViewDelegate oluşturduktan sonra hangi View’a tıklanıldığını bilmemiz için içerisinde bir index almamız lazım. Bunu da CustomStackTableViewTapGesture ile oluşturabiliriz.

//
//  CustomStackTableViewTapGesture.swift
//  custom-stack-table-view
//
//  Created by Ömer Sezer on 14.01.2023.
//

import UIKit

final class CustomStackTableViewTapGesture: UITapGestureRecognizer {
    var index: Int?
}

Son olarak ise CustomStackTableView oluşturmamız gerekiyor. Bu sınıf UIStackView’den kalıtım alacak ve bunun üzerinden geliştirmelerimizi yapacağız. Öncelikle buraya bir Delegate tanımlıyorum ve bu Delegate üzerinden işlemleri yapacağız. Dikey bir liste istediğim için Axis özelliğini dikey olarak ayarlıyorum.

//
//  CustomStackTableView.swift
//  custom-stack-table-view
//
//  Created by Ömer Sezer on 14.01.2023.
//

import UIKit

final class CustomStackTableView: UIStackView {
    var delegate: CustomStackTableViewDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init(coder: NSCoder) {
        super.init(coder: coder)
    }
}

extension CustomStackTableView {
    func configure() {
        self.axis = .vertical
        guard let delegate else {
            print("Delegate is nil")
            return
        }
        
        for index in 0...delegate.numberOfItems() - 1 {
            let item = delegate.itemForRowAtIndex(index: index)
            item.isUserInteractionEnabled = true
            
            let tap = CustomStackTableViewTapGesture(target: self, action: #selector(handleTap(_:)))
            tap.index = index
            
            item.addGestureRecognizer(tap)
            self.addArrangedSubview(item)
        }
    }
    
    @objc private func handleTap(_ sender: CustomStackTableViewTapGesture) {
        guard let delegate, let index = sender.index else {
            print("Delegate or index is nil")
            return
        }
        delegate.itemPressedAtIndex(index: index)
    }
}

Son olarak ise aşağıdaki gibi kullanabilirsiniz.

//
//  ViewController.swift
//  custom-stack-table-view
//
//  Created by Ömer Sezer on 14.01.2023.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet private weak var tableView: CustomStackTableView! {
        didSet {
            tableView.delegate = self
            tableView.configure()
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension ViewController: CustomStackTableViewDelegate {
    func itemPressedAtIndex(index: Int) {
        print("Item pressed at index \(index)")
    }
    
    func itemForRowAtIndex(index: Int) -> UIView {
        let label = UILabel()
        label.text = "\(index). User"
        return label
    }
    
    func numberOfItems() -> Int {
        return 1000
    }
}

Tabi listenin ekranda kayması için oluşturduğumuz CustomStackTableView’in UIScrollView içerisinde olması gerekiyor.

Oluşturduğumuz projeye buradan ulaşabilirsiniz. Swift hakkında daha fazla yazıya ise buradan ulaşabilirsiniz.

Sorularınız olursa mail veya yorum atarak bana ulaşmanız yeterli olacaktır. İyi çalışmalar.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir