How to create dynamic height for TableView cell textview using Swift? - swift

I am creating single Tableview custom cell row with top and bottom two textview. Here, bottom textview need to adjust height dynamically based on textview text length.
My Storyboard
enter image description here
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 280.0
}
//Choose your custom row height
private func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 280.0;
}
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.animals.count
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
cell.sourceTextView.text = “ABCD….”
return cell
}

Just do this
func adjustUITextViewHeight(arg : UITextView)
{
arg.translatesAutoresizingMaskIntoConstraints = true
arg.sizeToFit()
arg.scrollEnabled = false
}
In Swift 4 the syntax of arg.scrollEnabled = false has changed to
arg.isScrollEnabled = false.

Related

Weird display behaviour when selecting tableview row

I have this table view, that populates through Core Data. Everything looks fine, even when scrolling, until I press and hold any row - then that row distorts like in the second image below.
(source: staticflickr.com)
(source: staticflickr.com)
Here's the code to display the tableview
override func viewDidLoad() {
super.viewDidLoad()
animateBackground(colors)
tableView.delegate = self
tableView.dataSource = self
tableView.fetchData(fetchedResultsController as! NSFetchedResultsController<NSFetchRequestResult>)
self.tableView.tableFooterView = UIView(frame: .zero)
}
func numberOfSections(in tableView: UITableView) -> Int {
guard fetchedResultsController.sections?.count != nil else { return 0 }
return fetchedResultsController.sections!.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard fetchedResultsController.sections != nil else { return 0 }
let data = fetchedResultsController.sections![section]
return data.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SkillCell", for: indexPath) as! SkillCell
configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
return cell
}
func configureCell(cell: SkillCell, indexPath: NSIndexPath) {
let skill = fetchedResultsController.object(at: indexPath as IndexPath)
cell.skill = skill
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { }
}
From the code above, everything looks normal, yet this distortion occurs. Please help me to see why and how to stop it happening.
As the comment suggests, it's just a visual effect called selectionStyle of your UITableViewCell. Inside your cellForRowAt indexPath method, you can disable it like:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell") as! MyCell
cell.selectionStyle = .none // this removes the effect.
return cell
}
yes you should set tableView selection style to none.
1.Select the tableview in storyboard in the right panel set selection style to none.
or
2.in your tableview cellforrow method set
tableView.selectionstyle = none

How to expand tableview cell on click on button which is located outside the cell in the tableview?

There is a tableview cell and there is a more button which is located on the tableview not in the cell so I want that when the project run it show only five user data in the tableview cell and other user data is show when the user click on the more button(which is located out side the cell) how do I achieved this?
Thanks for help
You can find the prototype cell image
//Mark:TableViewDelegate
extension MembersViewController:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return imgarray.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblView.dequeueReusableCell(withIdentifier: "membTableCell", for: indexPath) as! membTableCell
cell.profiletabImg.image = imgarray[indexPath.row]
cell.namelbl.text = names[indexPath.row]
cell.positionlbl.text = "Ceo of code with color"
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
#IBAction func morebutton(sender:UIButton){
}
}
The tableview expands automatically if you add data to the array and call the tableview.reloadData() function.
From the Apple's Doc -
"Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view’s delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates() and endUpdates()."
#IBAction func moreBtnPressed(_ sender: Any) {
tableviewArray.append("Append your array with remaining items")
tableview.reloadData()
}
Return 5 in numberOfRowsInSection method if more button is not tapped.
When more button is tapped reload the tableview and return imgarray.count in numberOfRowsInSection method.
class TableViewController: UITableViewController {
var dataArr = [String]()
var expanded = false
override func viewDidLoad() {
super.viewDidLoad()
dataArr = (1..<25).map({ String($0) })
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "\(dataArr.count - 5) more", style: .plain, target: self, action: #selector(morebutton(_:)))
}
#objc func morebutton(_ sender: UIBarButtonItem) {
self.navigationItem.rightBarButtonItem = nil
expanded = true
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !expanded && !dataArr.isEmpty {
return 5
} else {
return dataArr.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier") ?? UITableViewCell(style: .default, reuseIdentifier: "reuseIdentifier")
cell.textLabel?.text = dataArr[indexPath.row]
return cell
}
}

UITABLE view sections with different prototype cells in each section

I have a table view with different sections and for each section it has different prototype cells. I have created the prototype cell in storyboard but I could not make more than one cell in cellForRowAtIndexPath. I have attached the whole code for reference.
This is my storyboard design
This is the final output screen which it should look like
import UIKit
class PlacePeopleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var friendlistTableView: UITableView!
var sectionHead = ["Friends", "Others"]
override func viewDidLoad() {
super.viewDidLoad()
friendlistTableView.delegate = self
friendlistTableView.dataSource = self
// Do any additional setup after loading the view.
}
// MARK: - tableview datasource & delegate
func numberOfSections(in tableView: UITableView) -> Int {
return sectionHead.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionHead[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 5
}else {
return 10
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCell
cell.placeName.text = "poland"
cell.placeAddress.text = "Simon Albania"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 79
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 15
}
}
Note : You can do this using only one cell. just hide/show the connect Button by checking some condition.
If you want to use different cells for different sections, inside your cellForRowAt indexPath method return your cells based on your section like below .
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCellOne
return cell
default:
let defaultcell = tableView.dequeueReusableCell(withIdentifier: "defaultcell") as! RecentVizzTableViewCellDefatult
return defaultcell
}
hope this will help to you. good luck.

Why is the width of cell in UItableview not same as width of screen in simulator?

The table cell is running shorter than it is supposed to be. (I use different background colour which shows difference width) The setting of cell is custom (only row height is change to 140). The playerCell class has nothing but some IBoutlets. Thanks.
(image: storyboard
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count: Int
if playerBank.count == 0
{
count = 1
}
else{
count = playerBank.count
}
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! playerCell
if playerBank.isEmpty{
let p = Player()
playerBank = setInvalidPlayer(pBank: p, userInput: userInputPlayerName)
}
let playerInBank: Player = playerBank[indexPath.row]
passImageUrl = cell.setPlayerCell(p: playerInBank)
urlBank.append(passImageUrl)
let bgColorView = UIView()
bgColorView.backgroundColor = UIColor.red
cell.selectedBackgroundView = bgColorView
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
myIndex = indexPath.row
DispatchQueue.main.async {
self.performSegue(withIdentifier: "ShowPlayerInfo", sender: self)
}
}
My first guess is that, while you have a custom cell with custom outlets, that there are no layout constraints in place. So the items that you put into the storyboard are retaining their intrinsic values and not adapting to the device screen size.
If you add constraints to those outlets, especially enough to where the width of the cell can be determined based on the rest of the elements, then your cell should display full width.

Change cell height but not elements in it

I have a prototypes cell that changes height when I touch up inside it; below how I made it:
class SquadreController: UITableViewController
{
var index: NSIndexPath = NSIndexPath()
override func viewDidLoad()
{
super.viewDidLoad()
DataManager.sharedInstance.createCori()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return DataManager.sharedInstance.arrayCori.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
let squadra = DataManager.sharedInstance.arrayCori[indexPath.row]
cell.backgroundColor = UIColor.clearColor()
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
index = indexPath
tableView.beginUpdates()
tableView.endUpdates()
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if index == indexPath
{
return 176
} else
{
return 88
}
}
}
Ok, it works perfectly. Now I need to put an UIImage in that cell, but I need that image were partially visible like this:
The final effect I would like to realize it's quite similar to this mokeup https://dribbble.com/shots/1293959-LiveSport-App: like the mokeup in my cell there will placed UIImage, labels, views, button.
This is it, if someone could help me with a step by step guide to do this or with some tutorial, I would be grateful!!!
I solved simply with set top, left, right constraints (not bottom) and height constraint to the UIImageView; so the image would not be resized but partially covered by the cell.