Customizing image in Custom TableView - ios

I want to add a corner radius to my image that is nested inside a custom cell, inside a custom table view using Swift in Xcode. Here is my code. Does anyone know how to apply .cornerRadius = 10?
struct Beer {
let title: String
let imageName: String
}
//Enter cell lines here for new beers
let data: [Beer] = [
Beer(title: "Helles Half Life", imageName: "HellesHalfLife"),
Beer(title: "Racemic Red Ale", imageName: "RedAle"),
Beer(title: "RSIPA", imageName: "RSIPA"),
Beer(title: "Stage II HAC", imageName: "HellesHalfLife"),
Beer(title: "Helleva Stage II Lager", imageName: "HellevaStageII"),
Beer(title: "Train of Four Stout", imageName: "TrainOfFour"),
Beer(title: "Patrick's Feeling Hazy", imageName: "PatricksFeelingHazy"),
Beer(title: "BIS 40", imageName: "BIS40"),
Beer(title: "40 Winks", imageName: "FortyWinks"),
Beer(title: "", imageName: ""),
]
override func viewDidLoad() {
super.viewDidLoad()
table.dataSource = self
table.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Beer = data[indexPath.row]
let cell = table.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.label.text = Beer.title
cell.iconImageView.image = UIImage(named: Beer.imageName)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) ->
CGFloat{
return 120
}
I tried adding table.layer.cornerRadius = 10 in the override func viewDidLoad() section under table.delegate.

in your TableViewCell Class File,
iconImageView.clipsToBounds = true
iconImageView.layer.cornerRadius = 10.0
or you can also add cornerRadius in cellForRowAt:
cell.iconImageView.image = UIImage(named: Beer.imageName)
cell.iconImageView.clipsToBounds = true
cell.iconImageView.layer.cornerRadius = 10.0

You can add imageview inside a view and then
cell.yourImageViewContainerView.layer.cornerRadius = 10.0
cell.yourImageViewContainerView.clipsToBounds = true
or
cell.yourImageViewContainerView.layer.cornerRadius = 10.0
cell.yourImageView.clipsToBounds = true

Related

I'm Creating an demo on Expandeble Tableview, Expanding is working Fine... But facing issue while didselect row is tapped

Expanding and Collapsing is working fine tableview, Only facing issue while didselect row is tapped, I'm getting same index evry time after selecting a row. I'm getting the same out put, I want to pass the data to next view but output isn't working properly.
Here's My Details...
My OutPut
My Model
struct ItemList {
var name: String
var items: [String]
var collapsed: Bool
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
My ViewController Class
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var sections = [ItemList]()
var items: [ItemList] = [
ItemList(name: "Mac", items: ["MacBook", "MacBook Air"]),
ItemList(name: "iPad", items: ["iPad Pro", "iPad Air 2"]),
ItemList(name: "iPhone", items: ["iPhone 7", "iPhone 6"])
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
TableView Extension
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerHeading = UILabel(frame: CGRect(x: 5, y: 10, width: self.view.frame.width, height: 40))
let imageView = UIImageView(frame: CGRect(x: self.view.frame.width - 30, y: 20, width: 20, height: 20))
if items[section].collapsed{
imageView.image = UIImage(named: "collapse")
}else{
imageView.image = UIImage(named: "expand")
}
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 60))
let tapGuesture = UITapGestureRecognizer(target: self, action: #selector(headerViewTapped))
tapGuesture.numberOfTapsRequired = 1
headerView.addGestureRecognizer(tapGuesture)
headerView.backgroundColor = UIColor.red
headerView.tag = section
headerHeading.text = items[section].name
headerHeading.textColor = .white
headerView.addSubview(headerHeading)
headerView.addSubview(imageView)
return headerView
}
func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
let itms = items[section]
return !itms.collapsed ? 0 : itms.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
cell.textLabel?.text = items[indexPath.section].items[indexPath.row]
return cell
}
#objc func headerViewTapped(tapped:UITapGestureRecognizer){
print(tapped.view?.tag)
if items[tapped.view!.tag].collapsed == true{
items[tapped.view!.tag].collapsed = false
}else{
items[tapped.view!.tag].collapsed = true
}
if let imView = tapped.view?.subviews[1] as? UIImageView{
if imView.isKind(of: UIImageView.self){
if items[tapped.view!.tag].collapsed{
imView.image = UIImage(named: "collapsed")
}else{
imView.image = UIImage(named: "expand")
}
}
}
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = items[indexPath.row]
print("IndexPath :- \(row.name)")
}
}
If you look at the way you are setting the text in your cells in cellForRowAt:
cell.textLabel?.text = items[indexPath.section].items[indexPath.row]
You are saying:
get the ItemList object for indexPath.section from items array
get the String from that object's items array of this indexPath.row
However, in your didSelectRowAt:
let row = items[indexPath.row]
print("IndexPath :- \(row.name)")
You are saying:
get the ItemList object for indexPath.row from items array
print the .name property of that object
So, change your didSelectRowAt code to match your cellForRowAt logic:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedString = items[indexPath.section].items[indexPath.row]
print("IndexPath :- \(selectedString)")
// or, for a little more clarity
let sectionObject = items[indexPath.section]
let rowItem = sectionObject.items[indexPath.row]
print("IndexPath :- \(indexPath) // Section :- \(sectionObject.name) // Item :- \(rowItem)")
}

Leave A Comment With Json Wordpress in Xcode

i made app with Xcode in swift using my Wordpress backend and getting data with json, i can show users comment on my app but i want that users can also leave comments in the app, there should be an option for Leave a comment on post details file, this is my code for showing comments
#IBAction func commentViewController(_ sender: Any) {
let vc = CommentViewController()
vc.dataArray = jsonData["comments"].array
self.navigationController!.pushViewController(vc, animated: true)
}
self.commentButton.layer.borderWidth = 2
self.commentButton.layer.borderColor = baseColor.cgColor
self.commentButton.layer.cornerRadius = 4.0
self.commentButton.tintColor = baseColor
self.commentButton.setTitle("comments(\(jsonData["comments"].array?.count ?? 0))", for: .normal)
but i don't know how to make a comment box where users can also leave comment , thanks
This Is My CommentViewController:
var tableView: UITableView = UITableView()
var dataArray: Array<JSON>!
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Comments"
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationItem.largeTitleDisplayMode = .automatic
let attributes = [
NSAttributedString.Key.foregroundColor : navigationBarTextColor, NSAttributedString.Key.font: UIFont(name: "SFUIText-Medium", size: 34),
]
navigationController?.navigationBar.largeTitleTextAttributes = attributes as [NSAttributedString.Key : Any]
} else {
// Fallback on earlier versions
}
// Check if Post have comments
if(self.dataArray.count == 0){
self.view.backgroundColor = UIColor(red: 216 / 255, green: 216 / 255, blue: 216 / 255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: (UIScreen.main.bounds.width/2)-100, y: (UIScreen.main.bounds.height/2)-50, width: 200, height: 50))
label.text = "No Comments"
label.font = UIFont(name: "SFUIText-Regular", size: 18)
label.textAlignment = NSTextAlignment.center
self.view.addSubview(label)
}
else{
self.setupTable()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getDateFromString(String:String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let dateObj = dateFormatter.date(from: String)
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.string(from: dateObj!)
}
func setupTable(){
tableView = UITableView(frame: UIScreen.main.bounds, style: UITableView.Style.plain)
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: "commentViewCell", bundle: nil), forCellReuseIdentifier: "cell")
tableView.frame.size.height = UIScreen.main.bounds.height - 64
tableView.bounces = false
tableView.allowsSelection = false
self.view.addSubview(self.tableView)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.dataArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! commentViewCell
cell.commentText.text = String(htmlEncodedString: dataArray[indexPath.row]["content"].stringValue)
cell.name.text = String(htmlEncodedString:dataArray[indexPath.row]["name"].stringValue)
cell.date.text = getDateFromString(String: dataArray[indexPath.row]["date"].stringValue)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
So you have a "tableView" field where all comments are shown.
As Joakim Danielson advices, you should add UITextView to the bottom of your screen.
Because the table view can be too long to fit the screen height, it probably will be scrolled, so it's easier to add this text view as a cell.
So you can do this in a following way:
Change the size of tableView for leaving the comment at the end:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.dataArray.count + 1
}
Add the cell with text view, let's name it LeaveCommentCell
Return the LeaveCommentCell instance as the last cell:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.row == self.dataArray.count { // this is the last row
let cell = tableView.dequeueReusableCell(withIdentifier: "AddCommentCell", for: indexPath) as! LeaveCommentCell // your new cell
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "ShowCommentCell", for: indexPath) as! commentViewCell // please note identifiers should differ
cell.commentText.text = String(htmlEncodedString: dataArray[indexPath.row]["content"].stringValue)
cell.name.text = String(htmlEncodedString:dataArray[indexPath.row]["name"].stringValue)
cell.date.text = getDateFromString(String: dataArray[indexPath.row]["date"].stringValue)
return cell
}
Add a button (e.g. with text "Post") to LeaveCommentCell, subscribe for event when it's pressed, get comment text and send it to server.

Layout and sizing issues with TableViewCells that change height based on content inside - Swift 3

I'm building a simple messenger app that uses a tableview to display the messages. Each cell contains text and a stretchable background image. When messages are added to the tableview, they do change height to accommodate the text. However, whenever a single-line message is entered, the table view cell appears to be way too long for just a single line of text.
I think it has to do with the initial height and width of the tableviewcell, but I am not sure. How can I fix this to ensure the text bubble image encompasses the text but does not expand too much over it?
Screenshot of single and multi-lined texts:
Screenshot of long single-lined text for comparison:
I am using auto layout, if it helps.
ViewController code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
var texts: [String] = ["Hey, how are you?", "Good, you?", "Great!"]
var user: [Int] = [1, 0, 1]
let screenSize = UIScreen.main.bounds
#IBOutlet weak var tableView: UITableView!
#IBAction func sendMessage(_ sender: Any) {
if textBox.text != ""
{
let str:String = textBox.text
let retstr:String = insert(seperator: "\n", afterEveryXChars: 27, intoString: str)
let rand:UInt32 = arc4random_uniform(2)
addText(text: String(retstr), user: Int(rand))
}
}
#IBOutlet weak var textBox: UITextView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.texts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if (self.user[indexPath.row]==1)
{
let cell:CustomCell = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! CustomCell
cell.myCellLabel.text = self.texts[indexPath.row]
cell.myCellLabel.textAlignment = NSTextAlignment.left
cell.myCellLabel.sizeToFit()
cell.myBackgroundImage.image = UIImage(named: "bubbleReversed")?.resizableImage(withCapInsets: UIEdgeInsetsMake(60, 50, 60, 50))
return cell
}
else
{
let cell:CustomCellOther = self.tableView.dequeueReusableCell(withIdentifier: "cell2") as! CustomCellOther
cell.myCellLabel.text = self.texts[indexPath.row]
cell.myCellLabel.textAlignment = NSTextAlignment.right
cell.myCellLabel.sizeToFit()
cell.myBackgroundImage.image = UIImage(named: "bubble")?.resizableImage(withCapInsets: UIEdgeInsetsMake(60, 50, 60, 50))
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You tapped cell number \(indexPath.row).")
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = 10.0
tableView.rowHeight = UITableViewAutomaticDimension
tableView.reloadData()
}
func addText(text:String, user:Int)
{
if (self.texts.count > 20)
{
self.texts.remove(at: 0)
self.user.remove(at: 0)
}
self.texts.append(text)
self.user.append(user)
tableView.reloadData()
let indexPath = NSIndexPath(row: self.texts.count-1, section: 0)
tableView.scrollToRow(at: indexPath as IndexPath, at: .top, animated: true)
}
func insert(seperator: String, afterEveryXChars: Int, intoString: String) -> String {
var output = ""
intoString.characters.enumerated().forEach { index, c in
if index % afterEveryXChars == 0 && index > 0 {
output += seperator
}
output.append(c)
}
return output
}
}
My tableviewcell classes just contain a UIImageView and a label.

How to Show/Hide UITableView Header when scrolling up & down?

I have added a HeaderView(from .xib) to UITableView,it is showing properly when i load the ViewController.But how will i hide the tableView Header as i scroll up to any position of tableView and show HeaderView when i scroll down.If anyone could help me it will be appreciated. Below is my code:
class ViewController: UIViewController,UITableViewDataSource,UIScrollViewDelegate {
#IBOutlet var myTable : UITableView!
var array = ["See All Local Deals","Food & Drink","Kids Activities","Taxi" , "Shopping" , "Local Tradesmen" , "Tattoo shop" , "Car Hire" , "Health & Fitness" , "Beauty & Spas" , "Home & Garden" , "Local Services" , "Nightlife" , "Wedding Planning" , "Holiday rentals"]
lazy var headerView : HeaderView? = {
return Bundle.main.loadNibNamed("HeaderView", owner: self, options: nil)?[0] as? HeaderView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.myTable.dataSource = self
self.myTable.tableHeaderView = headerView
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyCell
cell.lblText.text = array[indexPath.row]
return cell
}
}
In storyboard-> Select your tableview-> go with property inspector-> And change type to Grouped from Plain
In Swift 5.0
The programatic way of doing this is to use UITableView.Style.grouped:
self.tableView = UITableView(frame: .zero, style: .grouped)

Tableview background shows on simulator but is white when played on device

I currently have a tableview that has a clear background color so an image below it can be seen. On simulator it works great:
But when it's played on a device the background turns white:
The app is still functional but it would be nice to keep the background image.
This is my code:
class TabBarController: UITabBarController, UITableViewDelegate, UITableViewDataSource {
var tabBarItems: [UIViewController] = []
var areMessagesVisible: Bool = false
var titleForTabBars: [String] = ["Home", "Inbox", "Rewards", "My Card", "Locations", "My Profile", "Account Activity", "Invite Friends", "About Us", "Settings", "Help"]
var iconNames: [String] = ["Glass", "Mail Tab Bar Icon", "Rewards Tab Bar Icon", "TabBar card icon", "Locations Tab Bar Icon", "", "", "","","",""]
var controllersStoryboardId: [String] = ["homeNavController", "inboxNavController", "rewardsNavController", "cardNavController", "locationsNavController", "myProfileNavController", "accountActivityNavController", "inviteFriendsNavController", "aboutUsNavController", "settingsNavController", "helpNavController" ]
// to manage moreTableView
var moreTableView: UITableView = UITableView()
var currentTableViewDelegate: UITableViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.customizeMoreTableView()
//to REMOVE
areMessagesVisible = true
if !areMessagesVisible{
self.titleForTabBars.removeAtIndex(4)
self.controllersStoryboardId.removeAtIndex(4)
self.iconNames.removeAtIndex(4)
}
for i in 0 ..< controllersStoryboardId.count{
tabBarItems.append(UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier(controllersStoryboardId[i]) as? UINavigationController ?? UINavigationController())
}
// change background image
let backgroundImageView = UIImageView(image: UIImage(named: "Blank Settings"))
backgroundImageView.frame = view.frame
backgroundImageView.contentMode = .ScaleAspectFill
moreNavigationController.topViewController?.view.addSubview(backgroundImageView)
moreNavigationController.topViewController?.view.sendSubviewToBack(backgroundImageView)
let backgroundImageView2 = UIImageView(image: UIImage(named: "background3"))
backgroundImageView2.frame = view.frame
backgroundImageView2.contentMode = .ScaleAspectFill
moreNavigationController.topViewController?.view.addSubview(backgroundImageView2)
moreNavigationController.topViewController?.view.sendSubviewToBack(backgroundImageView2)
//change nav bar color
moreNavigationController.navigationBar.barStyle = UIBarStyle.BlackOpaque
moreNavigationController.navigationBar.barTintColor = UIColor.blackColor()
moreNavigationController.navigationBar.tintColor = UIColor.whiteColor()
}
override func viewWillAppear(animated: Bool) {
for i in 0 ..< tabBarItems.count{
tabBarItems[i].tabBarItem = UITabBarItem(title: titleForTabBars[i], image: UIImage(named: iconNames[i]), selectedImage: UIImage(named: iconNames[i]))
}
self.viewControllers = tabBarItems
}
func customizeMoreTableView(){
moreTableView = self.moreNavigationController.topViewController!.view as? UITableView ?? UITableView()
currentTableViewDelegate = moreTableView.delegate;
moreTableView.delegate = self
moreTableView.dataSource = self;
moreTableView.registerClass(MoreTableViewCell.self, forCellReuseIdentifier: "MoreTableViewCell")
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let moreCell = tableView.dequeueReusableCellWithIdentifier("MoreTableViewCell", forIndexPath: indexPath) as? MoreTableViewCell ?? MoreTableViewCell()
moreCell.textLabel?.text = titleForTabBars[indexPath.row + 4]
moreCell.textLabel?.textColor = UIColor.whiteColor()
moreCell.imageView?.image = UIImage(named: iconNames[indexPath.row + 4])
moreCell.backgroundColor = UIColor.clearColor()
return moreCell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titleForTabBars.count - 4
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
currentTableViewDelegate?.tableView!(tableView, didSelectRowAtIndexPath: indexPath)
}
}
there could be two reasons.
the uitableviewcell background is not clear
your image reference is not added in the project target you are running. it happens some times. plz double check.
In your tableview datasource try to add following code and it worked in my case
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell=tableView.dequeueReusableCellWithIdentifier("cellidentifier")!
cell.backgroundColor=UIColor.clearColor()
return cell
}

Resources