design UI of app using tablview in swift - ios

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

Related

How can I animate the progressBar in a custom prototype cell?

I'm trying to have the following animation in my custom UITableViewCell:
When a user checks off a task, the progressBar should go from 0.0 to 1.0 in 5 seconds
What I've tried
Doing the animation in the delegate method in the TableVC:
let cell = tableView.cellForRow(at: IndexPath(item: indexSection!, section: indexRow!)) as? TaskCell
cell?.progressBar.setProgress(1.0, animated: true)
This doesn't work because it seems like the cell doesn't exist (print(cell!) gives a fatal error)
Doing the animation in TaskCell.swift
#IBAction func checkBoxAction(_ sender: Any) {
if items![indexRow!].checked {
delegate?.changeButton(state: false, indexSection: indexSection!, indexRow: indexRow!, itemID: itemID)
UIView.self.animate(withDuration: 1.0) {
self.progressBar.setProgress(0.0, animated: true)
}
} else {
delegate?.changeButton(state: true, indexSection: indexSection!, indexRow: indexRow!, itemID: itemID)
UITableViewCell.animate(withDuration: 5.0) {
self.progressBar.setProgress(1.0, animated: true)
}
}
}
This does set the progress bar, but it doesn't animate it. The progress bar abruptly changes. This is what happens
Could anyone shine a light on what I'm doing wrong? Am I calling the animation function incorrectly or am I doing it in the wrong place?
Thanks,
Matt
I have just created a simplified example and for me the following code works:
CustomTableViewCell
class CustomTableViewCell: UITableViewCell
#IBOutlet weak var progressView: UIProgressView!
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 startButtonDidTap(_ sender: UIButton) {
UIView.animate(withDuration: 2) {
self.progressView.setProgress(0.5, animated: true)
}
}
}
ViewController
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "reuseID", for: indexPath) as? CustomTableViewCell else { return UITableViewCell() }
return cell
}
}
Of course you need a proper storyboard configuration in order to run my code...

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

table view inside table view in swift4

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

Table view cell not showing in table view controller

I'm new to swift and I'm trying to get my cells to show in tableView. I searched for questions here but none could help. The table loads fine and I get no errors regarding the tableView. Is there something I'm missing?
-I've double-checked the reuse identifier, they are the same
-I removed and readied the outlets
Here is my UITableViewController class:
class DrawerViewController: UITableViewController{
#IBOutlet weak var drawerTable: UITableView!
var currentCell = [DrawerModel]()
override func viewDidLoad() {
super.viewDidLoad()
addGradientToView(view: drawerTable)
let temp2Model = DrawerModel()
temp2Model.item = "Profile"
temp2Model.icon = "loginbackground2.jpg"
currentCell.append(temp2Model)
drawerTable.delegate = self
drawerTable.dataSource = self
//self.drawerTable.separatorStyle = UITableViewCellSeparatorStyle.none
//self.drawerTable.reloadData()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = drawerTable.dequeueReusableCell(withIdentifier: "drawerCell", for: indexPath) as! DrawerTableViewCell
let tempModel: DrawerModel
tempModel = currentCell[indexPath.row]
cell.thisLabel.text = tempModel.item
print("test1" + tempModel.item! as Any)
let currentImage = UIImage(named: "loginbackground2.jpg")
cell.thisImage = UIImageView(image: currentImage)
return cell
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("it ran")
return currentCell.count
}
func addGradientToView(view: UITableView)
{
//gradient layer
let gradientLayer = CAGradientLayer()
//define colors
gradientLayer.colors = [UIColor.init(rgb: 0x4b0082).cgColor, UIColor.init(rgb: 0xfa8072).cgColor]
//define locations of colors as NSNumbers in range from 0.0 to 1.0
//if locations not provided the colors will spread evenly
gradientLayer.locations = [0.0, 0.8]
//define frame
gradientLayer.frame = view.bounds
//insert the gradient layer to the view layer
view.layer.insertSublayer(gradientLayer, at: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is my UITableViewCell class:
class DrawerTableViewCell: UITableViewCell {
#IBOutlet weak var thisImage: UIImageView!
#IBOutlet weak var thisLabel: 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
}
}
If you are using UITableViewController (in your case DrawerViewController) it already have a tableView property embedded, which have a delegate and dataSource set to controller.
So when in your case next lines are redundant
drawerTable.delegate = self
drawerTable.dataSource = self
To fix just call tableView.reload() after currentCell.append(temp2Model)

How to make an expandable and collapsable UITableView (parent and child cells) in swift?

I wanted to have a UITableView which is able to expand and collapse while clicking on cells.
When I load the page, I want the Tableview to be expanded like this and function collapse and expand by clicking on the header(see the date).
Any help is appreciated.
Thanks everyone. I have solved the problem at last.This is the final sample code.
1) //Arrays for header and Child cells.
var topItems = [String]()
var subItems = [String]()
//Section index reference
var selectedIndexPathSection:Int = -1
2) Added Two custom cells. - one as header and other as Cell.
// AgendaListHeaderTableViewCell.swift
import UIKit
class AgendaListHeaderTableViewCell: UITableViewCell {
#IBOutlet weak var agendaDateLabel: UILabel!
#IBOutlet weak var expandCollapseImageView: UIImageView!
#IBOutlet weak var headerCellButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Child cell:
// AgendaListTableViewCell.swift
import UIKit
class AgendaListTableViewCell: UITableViewCell {
#IBOutlet weak var agendaListContainerView: UIView!
#IBOutlet weak var moduleListTitleLabel: UILabel!
#IBOutlet weak var moduleDueOnStatusLabel: UILabel!
#IBOutlet weak var moduleLocationLabel: UILabel!
#IBOutlet weak var moduleStatusLabel: UILabel!
#IBOutlet weak var moduleDownLoadStatusImageView: UIImageView!
#IBOutlet weak var moduleStatusLeftSideLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
agendaListContainerView.layer.cornerRadius = 3.0
moduleStatusLabel.layer.borderWidth = 0.5
moduleStatusLabel.layer.borderColor = UIColor.clearColor().CGColor
moduleStatusLabel.clipsToBounds = true
moduleStatusLabel.layer.cornerRadius = 5.0
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
3) On View Controller:
// AgendaListViewController.swift
import UIKit
class AgendaListViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var agendaListTableView: UITableView!
var appUIColor:UIColor = UIColor.brownColor()
var topItems = [String]()
var subItems = [String]()
var selectedIndexPathSection:Int = -1
override func viewDidLoad() {
super.viewDidLoad()
topItems = ["26th April 2017","27th April 2017","28th April 2017","29th April 2017","30th April 2017"]
subItems = ["Monday","TuesDay","WednessDay"]
}
override func viewWillAppear(animated: Bool) {
self.title = "AGENDA VIEW"
self.automaticallyAdjustsScrollViewInsets = false
agendaListTableView.tableFooterView = UIView(frame: CGRectZero)
}
//tableview delegate methods
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 85;
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return topItems.count
}
func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return 35
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCellWithIdentifier("agendaTableViewHeaderCellD") as! AgendaListHeaderTableViewCell
headerCell.agendaDateLabel.text = topItems[section]as String
//a buttton is added on the top of all UI elements on the cell and its tag is being set as header's section.
headerCell.headerCellButton.tag = section+100
headerCell.headerCellButton.addTarget(self, action: "headerCellButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
//minimize and maximize image with animation.
if(selectedIndexPathSection == (headerCell.headerCellButton.tag-100))
{
UIView.animateWithDuration(0.3, delay: 1.0, usingSpringWithDamping: 5.0, initialSpringVelocity: 5.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
headerCell.expandCollapseImageView.image = UIImage(named: "maximize")
}, completion: nil)
}
else{
UIView.animateWithDuration(0.3, delay: 1.0, usingSpringWithDamping: 5.0, initialSpringVelocity: 5.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
headerCell.expandCollapseImageView.image = UIImage(named: "minimize")
}, completion: nil)
}
return headerCell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if( selectedIndexPathSection == section){
return 0
}
else {
return self.subItems.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let childCell = tableView.dequeueReusableCellWithIdentifier("agendaTableViewCellID", forIndexPath: indexPath) as! AgendaListTableViewCell
childCell.moduleListTitleLabel.text = subItems[indexPath.row] as? String
childCell.moduleLocationLabel.text = subItems[indexPath.row] as? String
childCell.moduleDueOnStatusLabel.text = subItems[indexPath.row] as? String
return childCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
//button tapped on header cell
func headerCellButtonTapped(sender:UIButton)
{
if(selectedIndexPathSection == (sender.tag-100))
{
selectedIndexPathSection = -1
}
else {
print("button tag : \(sender.tag)")
selectedIndexPathSection = sender.tag - 100
}
//reload tablview
UIView.animateWithDuration(0.3, delay: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve , animations: {
self.agendaListTableView.reloadData()
}, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The sample can be downloaded # https://github.com/alvinreuben/Expand-ColllapseTableView
**Try to implement below**
import UIKit
class BankDepositsHistoryVC: UIViewController {
#IBOutlet weak var tableView: UITableView!
let NORMAL_HEIGHT:CGFloat = 90
let EXPANDABLE_HEIGHT:CGFloat = 200
var SECTION_OTHER_CARDS = 0
var expandableRow:Int = Int()
override func viewDidLoad() {
super.viewDidLoad()
self.expandableRow = self.historyData.count + 1 // initially there is no expanded cell
self.tableView.reloadData()
}
// MARK: - TableViewDelegate Setup
extension BankDepositsHistoryVC : UITableViewDelegate,UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.historyData.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
let value = indexPath.section
let row = indexPath.row
switch (value){
case SECTION_OTHER_CARDS:
switch (row){
case self.expandableRow:
return EXPANDABLE_HEIGHT
default:
return NORMAL_HEIGHT
}
default:
return 0
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DepositsHistoryCell", forIndexPath: indexPath) as! DepositsHistoryCell
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.expandableRow = indexPath.row // provide row to be expanded
//self.tableView.reloadSections(NSIndexSet(index: indexPath.row), withRowAnimation: UITableViewRowAnimation.Fade)
self.tableView.reloadData()
}
}
with the help of below method you can do that
for objective-c
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
for swift
func tableView(_ tableView: UITableView,heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
just change the height for a row when its get clicked and reload the section.
when you design any cell in storyboard don't put bottom constraint on the expandable part.just put top and height constraint.Hope this help :)

Resources