Merging static table view with a UIViewController - ios

I'm currently trying to build a screen that contains 2 UIButton, and 1 UIImageView.
Below these UI Elements, I want to add a static table view that would contain 1 UITextField for each cell in order to create a kind of scrollable form.
The error I'm having is the following one:
Static table views are only valid when embedded in UITableViewController instances
While it doesn't seem possible to create a static table view without a table view controller, I was wondering if there could be any way to get the same result as my initial idea?
Please note that I'm building my UI using storyboard.
Here's a screenshot of what I was trying to build initially:
EDIT: I finally decided to use a static view controller, and implemented the buttons in a cell and the other textfields in different cells. Thank you all for your help.

You can add the UITableViewController as a childViewController to your bigger UIViewController (parentVC)
Then manage parentVC's view hierarchy so that you can achieve the 2 UIButton, 1 UIImageView and a table view at the bottom

In Xcode 10.2 you can use Container View to implement the UI you described. Drag and drop a container view object to the required view controller in your storyboard scene:
Then add UITableViewController instance to your storyboard scene:
Set Static Cells for it's Content:
Then right-click on Content View that you added in one of the previous steps, and setup it as described on the following screenshots:
Setup constrains and cells content. Then you will see something like that on your testing device:

I think you should manage this adding elements in a UIScrollView, there's no need to use a UITableView. So you can scroll all the contents when you show the keyboard

A static tableview is nothing more than a UITableViewController handling the UITableView's UITableViewDataSource methods on your behalf.
You can simply add a UITableView to your UIViewController, set the UITableView datasource to your UIViewController and implement the methods as appropriate.
e.g.
class MyViewController: UIViewController, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
tableview.datasource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create UITableViewCell
}
}

Related

How to pin to top in a TableView in Swift?

I have a tableView with hundreds of cells. I want to add a feature to pin to top favorite cells, for example by swipe. Is there a way to do that? Or is it easier to have a different tableView with favorite cells?
Section for this.
Add your favorites to view, you can create it using storyboard or programmatically using following code. If you use storyboard, create and make a reference to the tableViewController and just return in this code.
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
// create and return yourView
}

TableViewCell Listener with Swift

Good Evening!
I have a specific question about Xcode (Swift) and the TabelView Layout.
My App has until now 1 View within a Container in this Container is a UITableViewController embeded which shows a nice static table view.
My mistake is how I can register when a User click on one of this table view cells?
The method:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//CODE TO BE RUN ON CELL TOUCH
}
doesnt work for me - the method is not called, an alert inside of this method is not shown.
Perhaps a false file structure? In my main storyboard I connected a Swift file with the UITableViewController which is inside of the container of the main view controller. Code of the File ist the basic:
import UIKit
class test: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
How can I register when a User click on a TableViewCell? For example showing an alert?
Please help me, I'm really new in iOS development.
Thanks!
Here are two pictures of my project-structure:
storyboard-structure
tableView-structure
A functioning table view requires three table view data source methods. make sure to add them .
func numberOfSectionsInTableView(tableView: UITableView) -> return Int number of section
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ->return Int number of rows in section
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> return UITableViewCell that populate the cell data
hope it help !!
A really silly mistake... The code was absolutely correct - the problem was in the main.swift file, the file within the container.
Above the container I've added a searchBar and used the following code to hide the keyboard by clicking outside the searchbar: https://stackoverflow.com/a/27079103/3849220
This code crashed my touch Events in the whole View - also "above" the container... dismissKeyboard() was called before the tableView function.
#Paulw11
A big thank you for your example project! It helps me really much to understand the logic and searching the mistake. Thank you!
I replaced the code and write a little own script that hide the keyboard by clicking a "done" button. Now it works!
Thanks at all!

UITableViewController as subview swift

I'm trying to make my first app and I'm stuck at this point.
My app looks like snapchat, a horizontal scrollview and the left part is composed of a tableview.
So, in this left part I put as a subview a tableViewController. The problem is the cells are always empty ! The table view is showing with the right cell's height but cells are empty.
I'm sure you can help me, thank you !
I make the subview here
Link with cells here
Please be ensure that override necessary methods in table view controller and balance calls in adding child view controller code rutin.One more last thing when adding child view controller you should provide correct size to controller view.
for adding table view controller as a child view controller
guard let list = R.storyboard.dashboard.addressesController()else {
return
}
self.list = list
self.addChildViewController(list)
self.scroll.addSubview(list.view)
list.didMoveToParentViewController(self)
list.tableView.layoutIfNeeded()
list.view.snp_makeConstraints(closure: {
(make) in
make.left.equalTo(self.view).offset(10)
make.right.equalTo(self.view).offset(-10)
make.bottom.equalTo(self.scroll)
make.height.equalTo(list.tableView.contentSize.height)
make.top.equalTo(authorizedTop.snp_bottom).offset(10)
})
for extending table view controller
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier) as UITableViewCell
cell.textLabel?.text = self.tableData[indexPath.row]
return cell
}
I know this isn't an answer to you question, but I have a suggestion which might help you in the long run, and maybe help you debug your current problem:
How about splitting the tableViews' logic into separate UITableViewControllers? That way you avoid some gigantic common UIViewController. You can use the Container View in your storyboard, which can embed a UIViewController.

programmatically generate different static UITableviews

I've just joined StackOverflow and i'm struggling with a programming requirement with a iPhone app I'm developing in swift. I have a tableview list of different calculators and i would like to segue to another UITableView when a item is clicked to then do the detailed calculations for that tool.
I am likely to have lots of tools in the first table (>20) and so i don't want to use storyboard to draw up each new UITableView static table with a different segue for each one.
I wonder if anyone can give me some advice on how to programmatically code a presentation of a new UITableViewController with static cells when a item is clicked. I don't want to use storyboard so i would need to use code to both manage the presentation as well as the generation of the next UITableViewController with static cells.
I have been able to program a static tableview with a custom class programmatically and linked to a storyboard UITableViewController item but i want to do all this programmatically and cut out storyboard all together.
Any advice you could offer would be greatly appreciated.
Thanks.
A UITableViewController abstracts some things. It seems like maybe what you want to do is to separate things out and have a little more granular control.
You can do this fairly easily. You need 3 things to make this happen:
UITableView
UITableViewDataSource
UITableViewDelegate
A UITableViewController puts these all together for you. We'll have to create them ourselves.
To do this, we make a View Controller, and inherit UITableViewDataSource and UITableViewDelegate
class Example: UIViewController {
}
// MARK - UITableViewDataSource
extension Example: UITableViewDataSource {
// We need to implement some methods here
}
// MARK - UITableViewDelegate
extension Example: UITableViewDelegate {
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Handle the user clicking an item here
}
}
Three things left to do:
Create and show the table
Get the data to display in the table
Implement the delegate methods
 Creating the table
You should decide if you want to completely programatically create a UITableView, or have Interface Builder lay one out for you in a .xib, and you just link it up via an IBOutlet.
Assuming you want to do the former, you can do the following:
var table: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
table = UITableView(frame: view.bounds)
view.addSubview(table!)
table?.delegate = self
table?.dataSource = self
}
 Get the data
When you push this view controller from your previous view controller, be sure to set a variable on this view controller with your data. Assuming you have an array, it's as simple as something like:
exampleViewController.myData = someArray;
navigationController?.pushViewController(exampleViewController, animated: true)
(be sure to create the myData variable in your View Controller to take this)
Implement the delegate methods
Now we can implement the delegate methods to show the data. You may already be familiar this, but for the sake of completeness:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// You should really use dequeueReusableCellWithIdentifier here.
var cell = UITableViewCell()
cell.textLabel!.text = myData[indexPath.row]
return cell
}

How to use static cells in UITableView without using Storyboards?

I have an existing ViewController + xib in my project, and now I want to add a UITableView with static cells, like this:
But when I drag a UITableView onto my screen I don't have the "Content > Static" menu in the Attributes Inspector.
I've tried making my controller subclass UITableViewController, but that doesn't help -- I still don't get the option to use static cells in Attributes Inspector.
I've looked around on StackOverflow but haven't found any existing answers to this question. All the existing questions relate to Storyboards (which I'm not using) instead of xib files.
My guess is that Xcode does some kind of magic when you add a UITableViewController to a storyboard, but not when you change an existing xib to inherit from UITableViewController.
Any advice how how to add a table view with static cells to an existing xib?
Static table view cells are only available when using storyboards. However, if you aren't using storyboards for your entire UI you can still use them for individual screens instead of a collection of screens.
To do this you can create a UIStoryboard file with a single view controller on it that has it's File's Owner set to your custom view controller subclass. Set the VC's identifier to some value. When you want to display this, get the storyboard and then instantiate your view controller subclass by creating the VC from your storyboard.
UIStoryboard *tableViewStoryboard = [UIStoryboard storyboardWithName:#"your storyboard" bundle:nil];
CustomViewController = [tableViewStoryboard instantiateViewControllerWithIdentifier:#"custom identifier"];
You can present this VC as usual in your app.
This is a great way to start using storyboards without having to convert your entire app to use them.
This is doable without storyboards:
your controller must adopt protocols for tableview delegate and
source...UITableViewDelegate, UITableViewDataSource
Add a table view to your .xib; set the table view's style to "grouped"
Connect the table to a property in your controller (let's call it "yourTableView")
Add table view cells to the .xib as separate views...i.e. not as subviews of the table view...they'll be free floating in the .xib. (see example image below)
Add controls / labels etc to the table cells.
Assign unique strings to the "Identifier" field in Attributes for each table view cell.
Connect the table cells to other properties in the controller (sliderCell, switchCell, etc)
Connect the send events for the cells' controls to IBAction-ed methods in the controller
- (IBAction) handleSliderCell, etc.
In the viewDidLoad method of your controller, assign the delegate and source of the table view to the controller (self.yourTableControl.delegate = self; self.yourTableControl.dataSource = self;)
implement numberOfSectionsInTableView, numberOfRowsInSection, and cellForRowAtIndexPath in the controller
in tableView:cellForRowAtIndexPath:, return yourFirstCell, yourSecondCell, etc pointers for appropriate indexPath values
Events for controls for the table cells should go to your handler routines...
Example for step 4:
To expand on BVB's answer, when it comes to number 10, here are the Swift 3 snippets for your tableview delegate methods. Be sure to add outlets to all your cells in the xib.
When you manually create your table view sections, remember that indexPath is equal to a 2 dimensional array representing your table structure. for example, when indexPath is passed to tableView(cellForRowAt indexPath: IndexPath) is equal to [1][0], your cell will be placed in the first position of the second section.
Values can be pulled out of indexPath with the properties indexPath.row and indexPath.section. Using these values, you can manually construct your sections from your IBOutlets in whichever order you prefer.
#IBOutlet var is_enabled: UITableViewCell!
#IBOutlet var is_public: UITableViewCell!
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch(section){
case 0:
return "Cell 1"
case 1:
return "Cell 2"
default: return ""
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("index path here", indexPath)
if(indexPath.section == 0) {
return is_enabled
}
else if(indexPath.section == 1) {
return is_public
} else {
return is_enabled
}
}

Resources