{"id":2522,"date":"2023-01-14T23:43:21","date_gmt":"2023-01-14T20:43:21","guid":{"rendered":"https:\/\/sezeromer.com\/?p=2522"},"modified":"2023-01-14T23:50:45","modified_gmt":"2023-01-14T20:50:45","slug":"kendi-uitableviewimizi-nasil-olustururuz","status":"publish","type":"post","link":"https:\/\/sezeromer.com\/en\/kendi-uitableviewimizi-nasil-olustururuz\/","title":{"rendered":"How to Create Our Own UITableView?"},"content":{"rendered":"<p>Hello friends, in this article we will talk about how we can create a <strong>UITableView<\/strong> with <strong>Swift<\/strong>. In some cases, UITableView may not be enough or you may want to manage it yourself. In this case we can do it with <strong>UIScrollView<\/strong> and <strong>UIStackView<\/strong>.<\/p>\n<p>When we create our own UITableView, we will create 3 basic functions. These;<\/p>\n<ul>\n<li>How many Views will appear on the screen<\/li>\n<li>Which View will appear<\/li>\n<li>What will the view do when clicked<\/li>\n<\/ul>\n<p>We will create a protocol for these first. In this way, we will be able to delegate our own UITableView over the UIViewController.<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;swift&quot;,&quot;mime&quot;:&quot;text\/x-swift&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:true,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">\/\/\r\n\/\/  CustomStackTableViewDelegate.swift\r\n\/\/  custom-stack-table-view\r\n\/\/\r\n\/\/  Created by \u00d6mer Sezer on 14.01.2023.\r\n\/\/\r\n\r\nimport UIKit\r\n\r\nprotocol CustomStackTableViewDelegate {\r\n    func itemPressedAtIndex(index: Int)\r\n    func itemForRowAtIndex(index: Int) -&gt; UIView\r\n    func numberOfItems() -&gt; Int\r\n}\r\n<\/pre>\n<\/div>\n<p>After creating the CustomStackTableViewDelegate, we need to get an index in it to know which View was clicked. We can also create this with CustomStackTableViewTapGesture.<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;swift&quot;,&quot;mime&quot;:&quot;text\/x-swift&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:true,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">\/\/\r\n\/\/  CustomStackTableViewTapGesture.swift\r\n\/\/  custom-stack-table-view\r\n\/\/\r\n\/\/  Created by \u00d6mer Sezer on 14.01.2023.\r\n\/\/\r\n\r\nimport UIKit\r\n\r\nfinal class CustomStackTableViewTapGesture: UITapGestureRecognizer {\r\n    var index: Int?\r\n}\r\n<\/pre>\n<\/div>\n<p>Finally, we need to create a CustomStackTableView. This class will inherit from UIStackView and we will build on it. First of all, I define a Delegate here and we will do the transactions through this Delegate. Because I want a vertical list, I set the Axis property to vertical.<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;swift&quot;,&quot;mime&quot;:&quot;text\/x-swift&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:true,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">\/\/\r\n\/\/  CustomStackTableView.swift\r\n\/\/  custom-stack-table-view\r\n\/\/\r\n\/\/  Created by \u00d6mer Sezer on 14.01.2023.\r\n\/\/\r\n\r\nimport UIKit\r\n\r\nfinal class CustomStackTableView: UIStackView {\r\n    var delegate: CustomStackTableViewDelegate?\r\n    \r\n    override init(frame: CGRect) {\r\n        super.init(frame: frame)\r\n    }\r\n    \r\n    required init(coder: NSCoder) {\r\n        super.init(coder: coder)\r\n    }\r\n}\r\n\r\nextension CustomStackTableView {\r\n    func configure() {\r\n        self.axis = .vertical\r\n        guard let delegate else {\r\n            print(\"Delegate is nil\")\r\n            return\r\n        }\r\n        \r\n        for index in 0...delegate.numberOfItems() - 1 {\r\n            let item = delegate.itemForRowAtIndex(index: index)\r\n            item.isUserInteractionEnabled = true\r\n            \r\n            let tap = CustomStackTableViewTapGesture(target: self, action: #selector(handleTap(_:)))\r\n            tap.index = index\r\n            \r\n            item.addGestureRecognizer(tap)\r\n            self.addArrangedSubview(item)\r\n        }\r\n    }\r\n    \r\n    @objc private func handleTap(_ sender: CustomStackTableViewTapGesture) {\r\n        guard let delegate, let index = sender.index else {\r\n            print(\"Delegate or index is nil\")\r\n            return\r\n        }\r\n        delegate.itemPressedAtIndex(index: index)\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Finally, you can use it as follows.<\/p>\n<div class=\"wp-block-codemirror-blocks code-block \">\n<pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;swift&quot;,&quot;mime&quot;:&quot;text\/x-swift&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;lineWrapping&quot;:false,&quot;styleActiveLine&quot;:true,&quot;readOnly&quot;:true,&quot;align&quot;:&quot;&quot;}\">\/\/\r\n\/\/  ViewController.swift\r\n\/\/  custom-stack-table-view\r\n\/\/\r\n\/\/  Created by \u00d6mer Sezer on 14.01.2023.\r\n\/\/\r\n\r\nimport UIKit\r\n\r\nclass ViewController: UIViewController {\r\n\r\n    @IBOutlet private weak var tableView: CustomStackTableView! {\r\n        didSet {\r\n            tableView.delegate = self\r\n            tableView.configure()\r\n        }\r\n    }\r\n    \r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n    }\r\n}\r\n\r\nextension ViewController: CustomStackTableViewDelegate {\r\n    func itemPressedAtIndex(index: Int) {\r\n        print(\"Item pressed at index \\(index)\")\r\n    }\r\n    \r\n    func itemForRowAtIndex(index: Int) -&gt; UIView {\r\n        let label = UILabel()\r\n        label.text = \"\\(index). User\"\r\n        return label\r\n    }\r\n    \r\n    func numberOfItems() -&gt; Int {\r\n        return 1000\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Of course, the CustomStackTableView we created must be in the UIScrollView for the list to scroll on the screen.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-2525\" src=\"https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26-1024x588.png\" alt=\"\" width=\"1024\" height=\"588\" srcset=\"https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26-1024x588.png 1024w, https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26-300x172.png 300w, https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26-768x441.png 768w, https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26-1536x882.png 1536w, https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-14-at-23.36.26.png 2032w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2528\" src=\"https:\/\/sezeromer.com\/wp-content\/uploads\/2023\/01\/1.gif\" alt=\"\" width=\"425\" height=\"917\" \/><\/p>\n<p>You can find the project we created <a href=\"https:\/\/github.com\/omersezer\/swift-projects\/tree\/main\/custom-stack-table-view\">here<\/a>. You can find more articles about Swift <a href=\"https:\/\/sezeromer.com\/swift\/\">here<\/a>.<\/p>\n<p>If you have any questions, it will be enough to reach me by sending an e-mail or comment. Good work.<\/p>","protected":false},"excerpt":{"rendered":"<p>Hello friends, in this article we will talk about how we can create a UITableView with Swift. In some cases, UITableView may not be enough or you may want to manage it yourself. In this case we can do it with UIScrollView and UIStackView. When we create our own UITableView, we will create 3 basic [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1706,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[327,706],"tags":[961,8,7,440,960,328,959,958,740],"class_list":["post-2522","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-swift","category-swiftui","tag-customstacktableview","tag-omer","tag-omer-sezer","tag-sezer","tag-stacktableview","tag-swift","tag-uiscrollview","tag-uistackview","tag-uitableview"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/posts\/2522"}],"collection":[{"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/comments?post=2522"}],"version-history":[{"count":8,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/posts\/2522\/revisions"}],"predecessor-version":[{"id":2532,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/posts\/2522\/revisions\/2532"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/media\/1706"}],"wp:attachment":[{"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/media?parent=2522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/categories?post=2522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sezeromer.com\/en\/wp-json\/wp\/v2\/tags?post=2522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}