table view inside table view in swift4 - ios

I tried tableview inside tableview, sub tableview contains drop down of 4 fields and if click on sub table view row then it will hide and shown in the dropdown button. pls check my below code.
import UIKit
var empname = ["Alex","Henry","Smith","Carey","Stephen"]
var insideArr = ["Retired", "Newly Joined", "Resigned", "Closed" ]
class EmpViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView.tag == 100{
return empname.count
}
else{
return insideArr.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == 100{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DataCell
cell.emp.text = empname[indexPath.item] as? String
cell.btndropdown.tag = indexPath.row
cell.btndropdown.addTarget(self, action: #selector(self.btndrop(sender:)), for: UIControl.Event.touchUpInside)
cell.btndropdown.setTitle("Open", for: .normal)
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "InnerDataCell", for: indexPath) as! InnerDataCell
cell.role.text = insideArr[indexPath.item] as? String
return cell
}
}
#objc func btndrop(sender: UIButton!){
if(sender.isSelected == true){
sender.isSelected = false
}
else{
sender.isSelected = true
}
}
}
class InnerDataCell: UITableViewCell {
#IBOutlet weak var lblInsideName: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
class DataCell: UITableViewCell {
#IBOutlet weak var tblInsideTableView: UITableView!
#IBOutlet weak var sitename: UILabel!
#IBOutlet weak var btndropdown: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension DataCell{
func setTableViewDataSourceDelegate
<D:UITableViewDelegate & UITableViewDataSource>
(_ dataSourceDelegate: D, forRow row: Int){
tblInsideTableView.delegate = dataSourceDelegate
tblInsideTableView.dataSource = dataSourceDelegate
tblInsideTableView.reloadData()
}
}
Required output:
Emp1 select V
Emp2 select V
if click on Select button in 1st index, then
Emp1 Select V
Emp2 Select V
Retired
Newly Joined
Resigned
Closed
if click on closed option then it will be
Emp1 Select V
Emp2 Closed V

Related

ImageView not displaying

i'm practising doing a instagram clone, however when I run the app the default images and like label doesn't show up. where am I going.
this is the code for the feed
import UIKit
class Feed: UITableViewCell {
#IBOutlet weak var imageee: UIImageView!
#IBOutlet weak var like: UILabel!
#IBOutlet weak var user: UILabel!
#IBOutlet weak var comment: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated:
Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func likeButton(_ sender: Any) {
}
This is the feedController view controller.
import UIKit
class FeedController: UIViewController ,
UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableV: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableV.delegate = self
// tablev.datasource = self
tableV.dataSource = self
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCell(withIdentifier:"cellTable" , for: indexPath) as! Feed
cell.user.text = "testing12"
cell.like.text = "0"
cell.comment.text = "comment"
cell.imageee.image = UIImage(named: "select.png")
return cell
}
}
where am i going wrong?
I can show you one example,
For instance I have the follow ViewController .
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "cell")
}
}
extension ViewController : UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
cell.imageView?.image = UIImage(named: "calendar")
return cell
}
}
and this is the cell
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var customImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
and this its xib.
check if you add the image in the Assets.xcassets folder

Updating Label in Cell

I have a TableView which rows contain label and two buttons. What I wanna do is that when a user clicks the first button "Set Name", a pop up view comes up in which he can input text from keyboard. After hitting "Set", pop up view is dismissed and label inside a row containing the clicked button changes to the input text. I set the delegates but I cannot make label to change.
TableView:
import UIKit
class SetGame: UIViewController, UITableViewDelegate, UITableViewDataSource
{
var numOfPlayers = Int()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return numOfPlayers
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.Name.text = "Player \(indexPath.row + 1)"
cell.btn1.tag = indexPath.row
cell.btn2.tag = indexPath.row
return cell
}
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
#IBAction func setName(sender: UIButton)
{
let thisVC = storyboard?.instantiateViewController(withIdentifier: "SetName") as! SetName
thisVC.delegate = self
present(thisVC, animated: true, completion: nil)
}
#IBAction func setFingerprint(_ sender: UIButton)
{
}
#IBAction func unwindToSetGame(_ segue: UIStoryboardSegue)
{
print("unwinded to SetGame")
}
#IBOutlet weak var tableView: UITableView!
}
extension SetGame: nameDelegate
{
func named(name: String)
{
let indexP = IndexPath(row: 0, section: 0)
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexP) as! TableViewCell
cell.Name.text = "bkjhvghcjhkv"
//wanted to see if it changes first cell. But doesn't work
}
}
TableViewCell Class:
import UIKit
class TableViewCell: UITableViewCell
{
override func awakeFromNib()
{
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
}
#IBOutlet weak var Name: UILabel!
#IBOutlet weak var btn1: UIButton!
#IBOutlet weak var btn2: UIButton!
}
Pop up View:
import UIKit
protocol nameDelegate
{
func named(name: String)
}
class SetName: UIViewController
{
var delegate: nameDelegate!
override func viewDidLoad()
{
super.viewDidLoad()
window.layer.borderWidth = 1
window.layer.borderColor = UIColor.white.cgColor
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
#IBAction func closePopUp(_ sender: Any)
{
if input.text != ""
{
delegate.named(name: input.text!)
}
dismiss(animated: true, completion: nil)
}
#IBOutlet weak var input: UITextField!
#IBOutlet weak var window: UIView!
}
Replace this
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexP) as! TableViewCell
with
let cell = tableView.cellForRow(at:indexP) as! TableViewCell

design UI of app using tablview in swift

I want UI of my app to be similar like as shown in below image.
Using tableview i'm able to get Payment,Delivery,Build Team options as shown in image but for Build Profile,Manage Menu.. how do i do it using tableview ?
If not tableview for these options then what other control i can try.
this type of UI you are looking for and you can easily get by creating different Cell classes
UI Output :
Required Code
Step 1 - Create different Xib of table cell
class viewWithArrow: UITableViewCell {
#IBOutlet weak var headerLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
class viewWithShadow: UITableViewCell {
#IBOutlet weak var shadowView: UIView!{
didSet{
shadowView.addShadowToView(color: .black)
}
}
#IBOutlet weak var headerLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Adding Shadow Effect :
extension UIView {
func addShadowToView(color:UIColor)
{
self.layer.shadowColor = color.cgColor
self.layer.shadowOpacity = 0.2
self.layer.masksToBounds = false
self.clipsToBounds = false
self.layer.shadowOffset = CGSize(width: 0, height: 0)
self.layer.shadowRadius = 5
}
}
View controller
class ViewController: UIViewController
{
var dataArray : [String] = ["11","22","33","44","55","66"]
#IBOutlet weak var homeVcTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
homeVcTableView.register(UINib(nibName: "viewWithShadow", bundle: nil), forCellReuseIdentifier: "viewWithShadow")
homeVcTableView.register(UINib(nibName: "viewWithArrow", bundle: nil), forCellReuseIdentifier: "viewWithArrow")
}
override func viewWillAppear(_ animated: Bool) {
self.homeVcTableView.delegate = self
self.homeVcTableView.dataSource = self
}
}
extension ViewController : UITableViewDataSource, UITableViewDelegate
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return dataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0,1:
let cell = self.homeVcTableView.dequeueReusableCell(withIdentifier: "viewWithShadow", for: indexPath) as! viewWithShadow
cell.headerLabel.text = dataArray[indexPath.row]
return cell
default:
let cell = self.homeVcTableView.dequeueReusableCell(withIdentifier: "viewWithArrow", for: indexPath) as! viewWithArrow
cell.headerLabel.text = dataArray[indexPath.row]
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.homeVcTableView.frame.size.height*0.1
}
}
Working code link - https://drive.google.com/open?id=18mSlWAU_e4XElox4H-oTpqg8clD_HKwu

Access to some values from another class in Swift

I have a TableViewCell class like this:
class CampaignsTableViewCell: UITableViewCell {
#IBOutlet weak var activateButton: UIButton!
#IBOutlet weak var titleCampaignPlaceholder: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
setUpButton()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
private func setUpButton(){
activateButton.backgroundColor = .clear
activateButton.layer.cornerRadius = 5
activateButton.layer.borderWidth = 1
activateButton.layer.borderColor = UIColor.blue.cgColor
}
}
And, in another class which is a ViewController I have my UITableView methods:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let rowNumber = indexPath.row
let cellIdentifier = "CampaignTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? CampaignsTableViewCell else {
fatalError("The dequeued cell is not an instance of TableViewCellController.")
}
cell.titleCampaignPlaceholder.text = campaignsArray[rowNumber].campaignName
return cell
}
I need to use my activateButton in my UITableView method in order to access to campaignsArray. I have another method which requieres values from that array, so I need that method is called every time activateButton is pressed from my UITableView.
Any idea ?
Thank you very much
What I like doing in those cases where you have a button inside your UITableViewCell is the following:
Give the cell a closure that is called when tapping on the button like so
class CampaignsTableViewCell: UITableViewCell {
... all your code....
// give your cell a closure that is called when the button is pressed
var onButtonPressed: ((_ sender: UIButton) -> ())?
#IBAction func buttonPressed(sender: UIButton) { // wire that one up in IB
onButtonPressed?(sender)
}
}
and then inside your TableViewController
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! CampaignsTableViewCell
cell.titleCampaignPlaceholder.text = campaignsArray[rowNumber].campaignName
cell.onButtonPressed = { [weak self] sender in
// Do your magic stuff here
}
return cell
Hope that helps
Your cell will get that event, not tableView. What you need to do is:
Create protocol inside your cell:
protocol CampaignsTableViewProtocol{
func actionButtonPressed(row: Int)
}
class CampaignsTableViewCell: UITableViewCell {
#IBOutlet weak var activateButton: UIButton!
#IBOutlet weak var titleCampaignPlaceholder: UILabel!
// keep info about row
var rowIndex: Int = -1
// create delegate that will let your tableView about action button in particular row
var delegate : CampaignsTableViewProtocol?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
setUpButton()
self. activateButton.addTarget(self, action: #selector(self.activatePressed), for: UIControlEvents.touchDown)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func activatePressed(){
self.delegate?.actionButtonPressed(row :rowIndex)
}
private func setUpButton(){
activateButton.backgroundColor = .clear
activateButton.layer.cornerRadius = 5
activateButton.layer.borderWidth = 1
activateButton.layer.borderColor = UIColor.blue.cgColor
}
}
Your tableViewController needs to adopt this protocol:
class MyTableViewController: UITableViewDelegate, UITableViewDataSource, CampaignsTableViewProtocol {
// rest of the code
}
Also, you will need to implement delegate function in your tableViewController:
func actionButtonPressed(row: Int) {
// get campaign you need
let campaign = campaignsArray[row]
// rest of the code
}

how to handle button click for each button in each row of UITableView

I have a UITableView (with a Custom class called CellModelAllNames for each row). Each Row has a Label and a button.
My question is: When btn_addRecording (i.e. the '+' button is clicked on any/each of the rows, how do I get the lbl_name.text, the label name shown, and show a pop up in the ViewController itself. I want to get additional information in the pop up and then save all the info (including the lbl_name to a database).
CellModelAllNames for each row layout:
import UIKit
class CellModelAllNames: UITableViewCell {
#IBOutlet weak var lbl_name: UILabel!
#IBOutlet weak var btn_addRecording: UIButton!
#IBAction func btnAction_addRecording(sender: AnyObject) {
println("clicked on button in UITableViewCell")
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func setCell(setBabyName: String) {
self.lbl_name.text = setBabyName
}
}
Here's the code of my ViewController:
import UIKit
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tbl_allNames: UITableView!
var arrayOfNames: [Name] = [Name]()
override func viewDidLoad() {
super.viewDidLoad()
self.tbl_allNames.delegate = self
self.tbl_allNames.dataSource = self
self.tbl_allNames.scrollEnabled = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:CellModelAllNames = self.tbl_allNames.dequeueReusableCellWithIdentifier("CellModelAllNames") as! CellModelAllNames
let name = arrayOfNames[indexPath.row]
cell.setCell(name.name)
println("in tableView, cellforRowatIndex, returning new cells")
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfNames.count
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
}
You can use standard UIKit methods to get the cell and its data:
func tappedButton(sender : UIButton) {
let point = sender.convertPoint(CGPointZero, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)!
let name = arrayOfNames[indexPath.row]
// do something with name
}
You can add button action in your ViewController
1) In your function cellForRowAtIndexPath assign button's tag as index (ie. indexPath.row)
cell.btn_addRecording.tag = indexPath.row
2) Add target and action for your button :
cell.btn_addRecording.addTarget(self, action: "buttonPressed:", forControlEvents: .TouchUpInside)
3) Add action in ViewControler (ie. save info in database)
func buttonPressed(button: UIButton!)
{
// Add your code here
let name = arrayOfNames[button.tag]
}

Resources