I am implementing a swipe to delete feature on all UITableViewCell in my UITableView. In the same time I would like use a custom button, and for this purpose, this tutorial came in handy: Custom edit view in UITableViewCell while swipe left. Objective-C or Swift
(I went with the 4th solution). So far, I am satisfied with my overall result as it work out just well. However, I have noticed that in my case, when swiping on the cell, the cell travel does not stop just after the hidden button is unveiled, rather is continues and it unveils some gray space. Once the cell is released, it bounces back, covering the gray space. The big question is, how do I disable this bounce effect and have the cell stop on slide just after the button is unveiled?
My problem is very similar to this one How to remove UITableViewCell swipe to delete bounce
. However, I've tried all UISwipeViewDelegate solutions and none of them work for me.
What I need it to be like:
What it's actually like:
This is my code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableView: UITableView!
lazy var rowHeight: CGFloat = {
return 82
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
let nibName = UINib(nibName: "TableViewCell", bundle: nil)
tableView.register(nibName, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.makeCellWith(image: "sampleImage", userName: "userNameSample")
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return rowHeight
}
// MARK: - Cell Sections
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame = UIEdgeInsetsInsetRect(view.frame, UIEdgeInsetsMake(0, 10, 0, 10))
}
// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
// MARK: - Slide to delete feature
fileprivate func whitespaceString(font: UIFont = UIFont.systemFont(ofSize: 15), width: CGFloat) -> String {
let padding: CGFloat = 20
let mutable = NSMutableString(string: "")
let attribute = [NSAttributedStringKey.font: font]
while mutable.size(withAttributes: attribute).width < width - (2 * padding) {
mutable.append(" ")
}
return mutable as String
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let whitespace = whitespaceString(width: rowHeight)
let deleteAction = UITableViewRowAction(style: .default, title: whitespace) { (action, indexPath) in
// do action on delete here
}
// create a color from pattern image and set the color as a background color of action
let view = UIView(frame: CGRect(x: 0, y: 0, width: rowHeight, height: rowHeight))
view.backgroundColor = UIColor.white
let imageSize: CGFloat = 50
let imageView: UIImageView = {
let iv = UIImageView()
let buttonImage = UIImage(named: "plusButton")
iv.image = buttonImage
return iv
}()
imageView.frame = CGRect(x: (view.frame.height - imageSize)/2,
y: (view.frame.width - imageSize)/2,
width: imageSize,
height: imageSize)
view.addSubview(imageView)
let image = view.image()
deleteAction.backgroundColor = UIColor(patternImage: image)
return [deleteAction]
}
// MARK: - Delete Object
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
fileprivate extension UIView {
func image() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
guard let context = UIGraphicsGetCurrentContext() else {
return UIImage()
}
layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Related
I am trying to make this, as in the first picture:
Image 1
Image 2
But the view somehow does not show up like I want it to. Here you can see my full project code:
import UIKit
import RealmSwift
import CVCalendar
class Test: UIViewController, UITableViewDelegate, UITableViewDataSource {
var myTableView: UITableView = UITableView()
var itemsToLoad: [String] = ["One", "Two", "Three"]
var myView = UIView()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 4/255, green: 4/255, blue: 4/255, alpha: 1.0)
self.navigationController?.navigationBar.barStyle = .black
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationItem.title = "Test"
self.navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Get main screen bounds
let screenSize: CGRect = UIScreen.main.bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
myView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 150)
myView.backgroundColor = .black
self.view.addSubview(myView)
myTableView.frame = CGRect(x: 0, y: 50, width: screenWidth, height: screenHeight-50);
myTableView.dataSource = self
myTableView.delegate = self
myTableView.backgroundColor = .blue
myTableView.layer.borderWidth = 3
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(myTableView)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return itemsToLoad.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.itemsToLoad[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("User selected table row \(indexPath.row) and item \(itemsToLoad[indexPath.row])")
}
}
Why won't it show up? The first picture is how I want it, then second picture is how it looks now.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if self.itemsToLoad[indexPath.row] != nil {
cell.textLabel?.text = self.itemsToLoad[indexPath.row]
cell.backgroundColor = .white
}else {
cell.backgroundColor = .blue
}
return cell
}
I have a TableViewController class :-
class SideMenuViewController: UITableViewController {
let tableViewFooter = UIView(frame: CGRect(x: 0, y: self.view.bounds.size.height + 80, width: self.view.bounds.width, height: 80))
tableViewFooter.backgroundColor = UIColor(patternImage: UIImage(named: "nav_drawer_footer.jpg")!)
tableView.tableFooterView = tableViewFooter
}
But using this code ..the view is under the last cell of tableView....i don't want this.
What I need is an ImageView / UIView at the Bottom of the table view Controller
let theHeight = view.frame.size.height //grabs the height of your view
let footer = UIView()
footer.backgroundColor = UIColor(patternImage: UIImage(named: "nav_drawer_footer.jpg")!)
footer.frame = CGRect(x: 0, y: theHeight - 150 , width: self.view.frame.width, height: 80)
self.view.addSubview(footer)
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView()
let imgView = UIImageView()
//Write UIImageView required code
footer.addSubView(imgView)
return footerView
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return HEIGHT_YOU_WANT
}
I would do this with UIViewController with separate UITableView and UIImageView instead of using UITableViewController.When using UITableViewController self.view is actually self.tableView, i.e. your image will be a subview of the UITableView and it will overlap the bottom rows. It is also better to use layout constraints than frame rects. As constraints code is somewhat a pain to write you can use SnapKit as I did here:
import SnapKit
class SideMenuViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
let tableViewFooter = UIView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
tableViewFooter.backgroundColor = UIColor(patternImage: UIImage(named: "nav_drawer_footer.jpg")!)
view.addSubview(tableView)
view.addSubview(tableViewFooter)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tableViewFooter.snp.makeConstraints { (make) -> Void in
make.width.equalTo(view.snp.width)
make.left.equalTo(view.snp.left)
make.bottom.equalTo(view.snp.bottom)
make.height.equalTo(80)
}
tableView.snp.makeConstraints { (make) in
make.top.equalTo(view.snp.top)
make.bottom.equalTo(tableViewFooter.snp.top)
make.width.equalTo(view.snp.width)
make.centerX.equalTo(view.snp.centerX)
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.backgroundColor = UIColor.blue
return cell
}
}
Edit: I am using SnapKit just so I don't write all this constraints code.The point is in the logic.
i am trying to make space between cells in UItableview i've checked google all posts i found is more than 3 years old , when i try to apply them i am getting so many errors, is it possible to make space between cells in UItableview ?
my Code :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell") as! ImageCell
cell.model = self.modelAtIndexPath(indexPath)
let url = URL(string: cell.model.imageName)
cell.imgBack.kf.setImage(with: url)
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//send back playlist count
if (section == 0) {
return self.lists_arr.count
}
return 0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated:true)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let imageCell = cell as! ImageCell
self.setCellImageOffset(imageCell, indexPath: indexPath)
}
//number of sections in table
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func modelAtIndexPath(_ indexPath: IndexPath) -> CellPlaylist {
return self.lists_arr[(indexPath as NSIndexPath).row % self.lists_arr.count]
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView == self.tblMain) {
for indexPath in self.tblMain.indexPathsForVisibleRows! {
if let imgCel : ImageCell = self.tblMain.cellForRow(at: indexPath) as? ImageCell {
self.setCellImageOffset(imgCel, indexPath: indexPath)
}
}
}
}
func setCellImageOffset(_ cell: ImageCell, indexPath: IndexPath) {
let cellFrame = self.tblMain.rectForRow(at: indexPath)
let cellFrameInTable = self.tblMain.convert(cellFrame, to:self.tblMain.superview)
let cellOffset = cellFrameInTable.origin.y + cellFrameInTable.size.height
let tableHeight = self.tblMain.bounds.size.height + cellFrameInTable.size.height
let cellOffsetFactor = cellOffset / tableHeight
cell.setBackgroundOffset(cellOffsetFactor)
}
The class of TableCell :
class ImageCell: UITableViewCell {
#IBOutlet weak var lblTitle: UILabel!
#IBOutlet weak var imgBack: UIImageView!
#IBOutlet weak var imgBackTopConstraint: NSLayoutConstraint!
#IBOutlet weak var imgBackBottomConstraint: NSLayoutConstraint!
let imageParallaxFactor: CGFloat = 70
var imgBackTopInitial: CGFloat!
var imgBackBottomInitial: CGFloat!
var model: CellPlaylist! {
didSet {
self.updateView()
}
}
override func awakeFromNib() {
self.clipsToBounds = true
self.imgBackBottomConstraint.constant -= 2 * imageParallaxFactor
self.imgBackTopInitial = self.imgBackTopConstraint.constant
self.imgBackBottomInitial = self.imgBackBottomConstraint.constant
}
func updateView() {
// self.imgBack.imageFromServerURL(urlString: self.model.imageName)
//self.getImage(url: self.model.imageName,imgView: self.imgBack)
//self.model.imageName
self.layer.cornerRadius = 10
self.layer.masksToBounds = true
self.layer.cornerRadius = 8
self.layer.shadowOffset = CGSize(width: 0, height: 3)
self.layer.shadowRadius = 3
self.layer.shadowOpacity = 0.3
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 8, height: 8)).cgPath
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
self.contentView.layoutMargins.top = 20
self.lblTitle.text = self.model.title
}
func setBackgroundOffset(_ offset:CGFloat) {
let boundOffset = max(0, min(1, offset))
let pixelOffset = (1-boundOffset)*2*imageParallaxFactor
self.imgBackTopConstraint.constant = self.imgBackTopInitial - pixelOffset
self.imgBackBottomConstraint.constant = self.imgBackBottomInitial + pixelOffset
}
}
The storyboard :
what i am getting
:
what i want :
Make Tablview BG colour white and set BG View colour in cell that you want to keep see in image i have set bgview BG colour is light greay and make BGview hight smaller then cell i mean if you want to set space 10 pixel keep Bg hight smaller then cell 10 pixel
Here is my cell
And here is out put
Update: UIEdgeInsetsInsetRect method is replaced now you can do it like this
contentView.frame = contentView.frame.inset(by: margins)
Swift 4 answer:
in your custom cell class add this function
override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentView.frame = UIEdgeInsetsInsetRect(contentView.frame, margins)
}
You can change values as per your need
Swift 4.2 solution
Inside UITableViewCell subclass
override func layoutSubviews() {
super.layoutSubviews()
let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
bounds = bounds.inset(by: padding)
}
Swift 5.0 solution
Inside UITableViewCell subclass
override func layoutSubviews() {
super.layoutSubviews()
let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
bounds = UIEdgeInsetsInsetRect(bounds, padding)
}
You can let every cell to take a section in group tableView, then you set the section's footer.
Try my code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.register(UINib.init(nibName: "VC1Cell", bundle: nil), forCellReuseIdentifier: "VC1Cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: -- tableview delegate
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let view:UIView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: self.view.bounds.size.width, height: 10))
view.backgroundColor = .clear
return view
}
func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 44
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:VC1Cell = tableView.dequeueReusableCell(withIdentifier: "VC1Cell") as! VC1Cell
return cell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 10.0
}
}
The result:
Building on Gulfam Khan's answer, the new way of setting the inset:
Swift 4:
override func layoutSubviews() {
super.layoutSubviews()
//set the values for top,left,bottom,right margins
let margins = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
contentView.frame = contentView.frame.inset(by: margins)
}
Swift 4:
override func layoutSubviews() {
super.layoutSubviews()
contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0))
}
Swift 5.2 Solution
override func layoutSubviews() {
super.layoutSubviews()
let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
bounds = bounds.inset(by: padding)
}
I need an auto scrolling Image slider in top of viewcontroller followed by list of some entities(dynamic cells with image and title). To implement that I have taken a uitableview and I'm adding scrollview to my first cell, and my code is as follows
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0{
return 200
}
else {
return 50
}
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if indexPath.row == 0 {
let sv = UIScrollView(frame: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height))
sv.auk.show(url: "url for image1")
sv.auk.show(url: "url for image2")
cell.addSubview(sv)
print("inside if")
}
else {
print("else")
cell.textLabel?.text = "cool"
}
return cell
}
I'm using this repository to create image slider which creates slider on a scrollview, So for first cell I have added scrollview. But as you can see in the picture the image slider reappears on multiple rows. Please tell me what is the mistake that I'm doing.In case if there is any better approaches please suggest .
Try taking a separate class for dynamic cells. Dequeue both the cells (static and dynamic cells) in the cellForRow method as follows:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row == 0 ? 200 : 50
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
scrollViewWidth = cell.frame.width
scrollViewHeight = cell.frame.height
let scrollView = prepareScrollView(width: scrollViewWidth, height: scrollViewHeight)
cell.addSubview(scrollView )
print("First row")
return cell
}
else {
let myCustomCell: MyCustomTableViewCellClass = tableView.dequeueReusableCell(withIdentifier: "MyCustomTableViewCellIdentieier", for: indexPath) as! MyCustomTableViewCellClass
myCustomCell.textLabel?.text = "Cool"
print("Other dynamic rows")
return myCustomCell
}
}
func prepareScrollView(_ width: Float, height: Float) -> UIScrollView {
let scrollViewFrame = CGRect(x: 0, y: 0, width: width, height: height)
let scrollView = UIScrollView(frame: scrollViewFrame)
scrollView.auk.show(url: "url for image1")
scrollView.auk.show(url: "url for image2")
return scrollView
}
Take a separate class as MyCustomTableViewCellClass of type UITableViewCell and subclass your dynamic cell with this class. Don't forget to give cell identifier as "MyCustomTableViewCellIdentieier"
After this, your static cell will dequeue only once and no chances od repeating UI elements
You can try this code in your table view cell class -
override func prepareForReuse() {
//set your lable and image view to nil
}
SideMenuTVCell is a my custom UITableViewCell class -
Hope like this you have your own class within this class you add prepareForReuse() method -
class SideMenuTVCell: UITableViewCell {
#IBOutlet weak var iconIView: UIImageView!
#IBOutlet weak var lblTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
}
override func prepareForReuse() {
//set your lable and image view to nil
self.iconIView.image = nil
self.lblTitle.text = nil
}
}
I'm having a problem with my parallax effect. I'm having a tableView and a ImageView above the tableView. Now when the user scrolls from the top I want to stretch the image a bit. But the problem is that my tableView keeps having a white background like you can see on the screenshot. So the image isn't visible. The screenshot is taken when the viewcontroller loads and then I just pull down as far as I can go. The tableView has backgroundColor .clear so I don't why it isn't working.
My code:
import UIKit
import PureLayout
class ViewController: UIViewController {
lazy var headerImageView: UIImageView = {
let imageView = UIImageView(forAutoLayout: ())
imageView.image = UIImage(named: "test")
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
lazy var tableView: UITableView = {
let tableView = UITableView(forAutoLayout: ())
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.isOpaque = false
tableView.backgroundColor = .clear
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "default")
tableView.tableFooterView = UIView()
tableView.showsVerticalScrollIndicator = false
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.headerImageView)
self.headerImageView.autoPinEdge(toSuperviewEdge: .left)
self.headerImageView.autoPinEdge(toSuperviewEdge: .right)
self.headerImageView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
self.headerImageView.autoSetDimension(.height, toSize: 100)
self.view.addSubview(self.tableView)
self.tableView.autoPinEdge(toSuperviewEdge: .left)
self.tableView.autoPinEdge(toSuperviewEdge: .right)
self.tableView.autoPinEdge(toSuperviewEdge: .bottom)
self.tableView.autoPinEdge(.top, to: .bottom, of: self.headerImageView)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "default", for: indexPath)
cell.textLabel?.text = "test"
cell.backgroundColor = .red
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Parallax functionality
let yOffset = scrollView.contentOffset.y * 0.2
let availableOffset = min(yOffset, 60)
let contentRectYOffset = availableOffset / self.headerImageView.frame.size.height
self.headerImageView.layer.contentsRect = CGRect(x: 0.0, y: contentRectYOffset, width: 1, height: 1)
}
}