Separator line UITableView - ios

I have this table view but the separator line looks like double line
In the storyboard I have this settings (table view):
Style: Plain
Separator: None
This is my code:
class ListTableViewCell: UITableViewCell {
#IBOutlet weak var transactionList: ransactionList!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
let separator = UIView(frame: CGRect(x: 8, y: bounds.size.height - 0.5, width: bounds.size.width - 22, height: 1))
separator.backgroundColor = UIColor.blue
contentView.addSubview(separator)
}
}
I expected something like this:

Here is how I made my own seperator line in the UITableViewDataSourceDelegate method.
//Separator Full Line
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = .zero
cell.layoutMargins = .zero
I believe I also had
separatorStyle="default"
on the tableview

Related

How to increase the width of custom cells in UITableView

I have created the UITableView with the custom UITableViewCell. But the problem which I am getting is the width of the cells is not the frame width though I have assigned in the CGReact. Please have a look over my code :
CustomTableViewCell Class:
import UIKit
class CustomTableViewCell: UITableViewCell {
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 76))
view.backgroundColor = .red
view.layer.applySketchShadow()
return view
}()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
lazy var iconTime : UIImageView = {
var object = UIImageView(frame: CGRect(x: 10, y: 54, width: 12, height: 12))
object.image = #imageLiteral(resourceName: "clock")
return object
}()
lazy var notification : UILabel = {
var object = UILabel(frame: CGRect(x: 10, y: 7, width: backView.frame.width, height: 40))
object.adjustsFontSizeToFitWidth = true
object.minimumScaleFactor = 0.5
object.font = object.font.withSize(28.0)
object.numberOfLines = 3
return object
}()
lazy var notificationTime : UILabel = {
var object = UILabel(frame: CGRect(x: 30, y: 40, width: backView.frame.width, height: 40))
object.adjustsFontSizeToFitWidth = true
object.minimumScaleFactor = 0.5
object.font = object.font.withSize(12.0)
return object
}()
override func layoutSubviews() {
contentView.backgroundColor = UIColor.clear
backgroundColor = UIColor.clear
backView.layer.cornerRadius = 5
backView.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
addSubview(backView)
[notification, notificationTime, iconTime].forEach(backView.addSubview(_:))
}
}
And my view controller as follows :
import UIKit
class UserModal {
var tableView = UITableView()
var notification: String?
var notificationTime : String?
init(notification: String, notificationTime: String) {
self.notification = notification
self.notificationTime = notificationTime
}
}
class newNotificationController : UIViewController {
var tableView = UITableView()
var userMod = [UserModal]()
override func viewDidLoad() {
super.viewDidLoad()
setTableView()
userMod.append(UserModal(notification: "Data ", notificationTime: "Time"))
userMod.append(UserModal(notification: "This is some Notification which needs to be populated in the Grid view for testing but lets see what is happening here!! ", notificationTime: "12-12-1212 12:12:12"))
userMod.append(UserModal(notification: "Data ", notificationTime: "Time"))
}
func setTableView() {
tableView.frame = self.view.frame
tableView.backgroundColor = UIColor.clear
tableView.delegate = self
tableView.dataSource = self
tableView.separatorColor = UIColor.clear
self.view.addSubview(tableView)
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.setNavigationBarHidden(false, animated: animated)
}
}
extension newNotificationController: UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userMod.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell else { fatalError("Unable to populate Notification History")}
cell.notification.text = userMod[indexPath.row].notification
cell.notificationTime.text = userMod[indexPath.row].notificationTime
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 85
}
}
Please have a look over the result:
I am not getting it why the width of my cells is the width of the frame. Any help will be highly appreciated. Thanks!!
The problem is in this code is frame width, somehow the width of the self is not the width of a device, so because of this, you are facing this issue.
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 76))
view.backgroundColor = .red
view.layer.applySketchShadow()
return view
}()
To resolve this issue you can set frame like this
let view = UIView(frame: CGRect(x: 10, y: 6, width: UIScreen.main.bounds.size.width - 10, height: 76))
You set the width your view
UIView(frame: CGRect(x: 5, y: 6, width: self.frame.width - 10,
height: 76))
tableView.frame = CGRect(x: 0, y: 0, width:
self.view.frame.size.width, height: self.view.frame.size.height)
you need to give constraint to the tableview. Top, Leading, Trailing, Bottom.
put this tableView.translatesAutoresizingMaskIntoConstraints = false line in your function
func setTableView() {
tableView.frame = self.view.frame
tableView.backgroundColor = UIColor.clear
tableView.delegate = self
tableView.dataSource = self
tableView.separatorColor = UIColor.clear
self.view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false //add this line
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
and change width: UIScreen.main.bounds.size.width - 10 it.
thanks..

iOS 11 - Unable to change Navigation Bar height

I am working on an application and I just upgraded to Xcode 9 / Swift 4 and also upgraded my iPhone to iOS 11.
The application was installed when I installed iOS 11 and all seemed OK until I run it from Xcode. Now I am stuck with the default NavBar height.
The code I was using to change the height is no longer working:
class CustomNavControllerVC: UINavigationController
{
let navBarHeight : CGFloat = 64.0
let navbarBackButtonColor = UIColor(red: 247/255, green: 179/255, blue: 20/255, alpha: 1)
override func viewDidLoad()
{
super.viewDidLoad()
print("CustomNavControllerVC > viewDidLoad")
}
override func viewDidLayoutSubviews()
{
print("CustomNavControllerVC > viewDidLayoutSubviews")
super.viewDidLayoutSubviews()
navigationBar.frame.size.height = navBarHeight
navigationBar.tintColor = navbarBackButtonColor
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// In my VCs
override func viewDidLoad()
{
customizeNavBar()
}
func customizeNavBar()
{
let navbarBackItem = UIBarButtonItem()
navbarBackItem.title = "Înapoi"
navigationItem.backBarButtonItem = navbarBackItem
let navbarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 55, height: 20))
navbarImageView.contentMode = .scaleToFill
let navbarLogo = UIImage(named: "NavBarLogo.png")
navbarImageView.image = navbarLogo
navigationItem.titleView = navbarImageView
}
So far the only thing I could find on this issue is this:
iOS 11 navigation bar height customizing
iOS11 customize navigation bar height
How to correctly set UINavigationBar height in iOS 11
But the info provided does not help, unfortunately.
Any ideas / suggestions?
Updated 2017.10.6
I had the same problem. Below is my solution. I assume that height size is 66.
My solution is working fine iOS 10, 11.
Please choose my answer if it helps you.
Create NavgationBar.swift
import UIKit
class NavigationBar: UINavigationBar {
//set NavigationBar's height
var customHeight : CGFloat = 66
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
}
override func layoutSubviews() {
super.layoutSubviews()
frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight)
// title position (statusbar height / 2)
setTitleVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
for subview in self.subviews {
var stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarBackground") {
subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
subview.backgroundColor = .yellow
}
stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarContent") {
subview.frame = CGRect(x: subview.frame.origin.x, y: 20, width: subview.frame.width, height: customHeight - 20)
subview.backgroundColor = UIColor(red: 20/255, green: 20/255, blue: 20/255, alpha: 0.4)
}
}
}
}
Set Storyboard
Set Custom NavigationBar class
Add TestView + Set SafeArea
ViewController.swift
import UIKit
class ViewController: UIViewController {
var navbar : UINavigationBar!
#IBOutlet weak var testView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//update NavigationBar's frame
self.navigationController?.navigationBar.sizeToFit()
print("NavigationBar Frame : \(String(describing: self.navigationController!.navigationBar.frame))")
}
//Hide Statusbar
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(false)
//Important!
if #available(iOS 11.0, *) {
//Default NavigationBar Height is 44. Custom NavigationBar Height is 66. So We should set additionalSafeAreaInsets to 66-44 = 22
self.additionalSafeAreaInsets.top = 22
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create BackButton
var backButton: UIBarButtonItem!
let backImage = imageFromText("Back", font: UIFont.systemFont(ofSize: 16), maxWidth: 1000, color:UIColor.white)
backButton = UIBarButtonItem(image: backImage, style: UIBarButtonItemStyle.plain, target: self, action: #selector(SecondViewController.back(_:)))
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
}
override var prefersStatusBarHidden: Bool {
return true
}
#objc func back(_ sender: UITabBarItem){
self.navigationController?.popViewController(animated: true)
}
//Helper Function : Get String CGSize
func sizeOfAttributeString(_ str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
return size
}
//Helper Function : Convert String to UIImage
func imageFromText(_ text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage
{
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
paragraph.alignment = .center // potentially this can be an input param too, but i guess in most use cases we want center align
let attributedString = NSAttributedString(string: text as String, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.paragraphStyle:paragraph])
let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Yellow is barbackgroundView. Black opacity is BarContentView.
And I removed BarContentView's backgroundColor.
That's It.

How to change separator height in UITableView Swift 3?

Although there a few answers already on this topic. None of them cover Swift 3 and they are from a long time ago. What is currently the best way to change the separator height in a UITableView in Swift 3?
Updated for Swift 3:
If you want to change the height of the UITableView separator, use the code below.
You should add it to the UITableViewCell method awakeFromNib() to avoid re-creation.
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let mScreenSize = UIScreen.main.bounds
let mSeparatorHeight = CGFloat(3.0) // Change height of speatator as you want
let mAddSeparator = UIView.init(frame: CGRect(x: 0, y: self.frame.size.height - mSeparatorHeight, width: mScreenSize.width, height: mSeparatorHeight))
mAddSeparator.backgroundColor = UIColor.brown // Change backgroundColor of separator
self.addSubview(mAddSeparator)
}
This is a correct way to do this.
First, in your ViewController you should set (tableView.separatorStyle = .none)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
}
}
Second, in your TableViewCell class your should create a separatorView.
And don't forget to inherit TableViewCell class for your cell.
class TableViewCell: UITableViewCell {
let separator = UIView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
separator.backgroundColor = .black
contentView.addSubview(separator)
}
override func layoutSubviews() {
super.layoutSubviews()
//Your separatorLineHeight with scalefactor
let separatorLineHeight: CGFloat = 1/UIScreen.main.scale
separator.frame = CGRect(x: self.contentView.frame.origin.x,
y: self.contentView.frame.size.height - separatorLineHeight,
width: self.contentView.frame.size.width,
height: separatorLineHeight)
}
}
Finally, you've got a thin separator line and, of course, you can increase this value what do you like.
For Those who want to do it using autolayout here is the code
var additionalSeparator:UIView = UIView()
override func awakeFromNib() {
super.awakeFromNib()
self.createSeparator()
}
func createSeparator() {
self.additionalSeparator.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.additionalSeparator)
}
func setConstraintForSeparator() {
self.additionalSeparator.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: self.separatorInset.left).isActive = true
self.additionalSeparator.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -self.separatorInset.right).isActive = true
self.additionalSeparator.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: 0).isActive = true
self.additionalSeparator.heightAnchor.constraint(equalToConstant: 1).isActive = true
self.additionalSeparator.backgroundColor = UIColor.greyishBrown
}
Try this Swift 3:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: YOUR_CELL_IDENTIFIER, for: indexPath) as! yourTableViewCell
let viewSeparatorLine = UIView(frame:CGRect(x: 0, y: cell.contentView.frame.size.height - 5.0, width: cell.contentView.frame.size.width, height: 5))
viewSeparatorLine.backgroundColor = .red
cell.contentView.addSubview(viewSeparatorLine)
return cell
}

The circle uiview is hidden when the cell is selected

The circle uiview is hidden when the cell is selected. How to fix it?
bringSubviewToFront not helping.
screenshot
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.selectedBackgroundView?.bringSubviewToFront(statusView)
}
Please help!
set your view's backgroundColor by override func setHighlighted(highlighted: Bool, animated: Bool)and func setSelected(selected: Bool, animated: Bool)like this:
class Cell: UITableViewCell {
var redView :UIView!
var yellowView :UIView!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
redView = UIView()
redView.frame = CGRect(x: 0, y: 10, width: 100, height: 20)
self.contentView.addSubview(redView)
yellowView = UIView()
yellowView.frame = CGRect(x: 200, y: 10, width: 100, height: 20)
self.contentView.addSubview(yellowView)
redView.backgroundColor = UIColor.redColor()
yellowView.backgroundColor = UIColor.yellowColor()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
redView.backgroundColor = UIColor.redColor()
yellowView.backgroundColor = UIColor.yellowColor()
}
override func setHighlighted(highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
redView.backgroundColor = UIColor.redColor()
yellowView.backgroundColor = UIColor.yellowColor()
}
}
While selecting the cells UIView, all painted in the background of the cell, so the UIView is hidden. If repaint after selection, then everything will be.
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
switch status {
case "8","9":
// print("Cancel")
statusView.backgroundColor = FlatUIColors.thunderBirdColor()
case "10","11","12":
// print("Success")
statusView.backgroundColor = FlatUIColors.nephritisColor()
case "20","21","22","23":
// print("Wait")
statusView.backgroundColor = FlatUIColors.wetAsphaltColor()
case "30","31":
// print("Processing")
statusView.backgroundColor = FlatUIColors.peterRiverColor()
default:
break
}
}
}

Different height in custom UITableViewCell

I want to create a custom UITableViewCell programmatically and cells have different height. But the height is fixed.
SingeTableViewCell.swift
class SingleTableViewCell: UITableViewCell {
var title = UILabel()
var content = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
self.setSeparator()
self.setTitle()
self.setContent()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setSeparator() {
let separator = UIView(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 10))
separator.backgroundColor = UIColor(hex: "#E7EBF2")
contentView.addSubview(separator)
}
func setTitle() {
let viewTitle = UIView(frame: CGRectMake(0, 10, UIScreen.mainScreen().bounds.width, 40))
viewTitle.backgroundColor = UIColor(hex: "#EEE")
viewTitle.layer.borderColor = UIColor.lightGrayColor().CGColor
viewTitle.layer.borderWidth = 1.0
self.title = UILabel(frame: CGRectMake(5, 0, UIScreen.mainScreen().bounds.width-5, 40))
self.title.textAlignment = NSTextAlignment.Center
self.title.font = self.title.font.fontWithSize(13)
viewTitle.addSubview(self.title)
contentView.addSubview(viewTitle)
}
func setContent() {
self.content = UILabel(frame: CGRectMake(0, 50, UIScreen.mainScreen().bounds.width, 400))
self.backgroundColor = UIColor.whiteColor()
contentView.addSubview(self.content)
}
}
I want cell's height is equals to frame's height.
Thank you and sorry for my bad english.
You can use Auto Layout to set self-sizing cell. Working with Self-Sizing Table View Cells
Alternatively, you can set the height with - tableView:heightForRowAtIndexPath: in UITableViewDelegate
class ViewController: UIViewController, UITableViewDelegate{
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// assume that you want to set height equal to 300 in 1st secion, and 200 in 2nd section.
let heights: [CGFloat] = [ 300,200 ]
return heights[indexPath.section]
}
}

Resources