UIImageView in table cell is not staying within frame original frame? - xcode

So this is what is happening:
I've added a red background color to the image view so you can see how much it's going over.
I've tried tableView(:willDisplayHeaderView:), I've tried checking off Subviews, I've tried AspectFit, AspectFill, & ScaletoFill But the UIImageView's keep going beyond their original boundaries and I don't understand why.
Here's some code from my UITableViewController:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("scheduleCell", forIndexPath: indexPath) as! ScheduleTableViewCell
let eventList = schedule?.schedule[dayOfWeek[indexPath.section]]!
let event = eventList![indexPath.row]
cell.labelEvent.text = event.act.rawValue
cell.labelTime.text = "\(event.getTime(event.start)) - \(event.getTime(event.end))"
return cell
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let tableViewCell = cell as! ScheduleTableViewCell
let eventList = schedule?.schedule[dayOfWeek[indexPath.section]]!
let event = eventList![indexPath.row]
tableViewCell.imageView?.image = UIImage(named: "\(schedule!.potato.mode)-\(event.act.rawValue)")
tableViewCell.imageView?.backgroundColor = UIColor.redColor()
tableViewCell.imageView?.contentMode = .ScaleAspectFit
}
And this is my custom cell class:
class ScheduleTableViewCell: UITableViewCell {
#IBOutlet weak var imageEvent: UIImageView!
#IBOutlet weak var labelEvent: UILabel!
#IBOutlet weak var labelTime: 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
}
}

First, setting the imageView's clipsToBounds property to true will prevent the image from spilling over the bounds of the imageView.
Second, the image is clearly bigger than the imageView, so I think the imageView is not spilling over, the image inside it is spilling over. So, you will either need to resize the image or use Scale*Fill modes to show the full image or crop it as appropriate.
HTH.

Related

Why the cell height is not changing on tapping the button once. It is working only when I tap the button twice

Click Here To see the UI of my app
Here In the image you can see the ui.
--> There is a tableView & a button on the main view.
--> I have taken a custom tableViewCell class
In the cell I have taken a UIView
Constraints Added To That View are:
centre horizontally, height, width, top & bottom constraint
I have added a outlet of the height constraint to the TVCell class
--> I have taken a button and added a event handler to it
--> Button Event handler:
In button event handler I am just changing the height of the view in the first cell and reloading the cell.
Now the problem is that height of the cell is changing when I tap on the button. But its happening only when I tap one the button twice. So I want to know why is it happening. Here I am adding my code below.
I have one solution for this problem which you can see after you see after the code of the ViewController & TableViewCell Class
VIEW CONTROLLER CLASS
import UIKit
class ViewController: UIViewController,UITableViewDataSource{
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.separatorColor = UIColor.black
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
return cell
}
#IBAction func buttonAction(_ sender: Any) {
let indexPath = IndexPath(row: 0, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
if cell.viewHeightConstraint.constant == 75 {
cell.viewHeightConstraint.constant = 10
}
else{
cell.viewHeightConstraint.constant = 75
}
tableView.reloadRows(at: [indexPath] , with: UITableView.RowAnimation.automatic)
}
}
TABLEVIEWCELL CLASS
import UIKit
class TableViewCell: UITableViewCell {
#IBOutlet weak var viewHeightConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
//Setting View Height To 75
viewHeightConstraint.constant = 75
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
You can get this source code from this link below
https://github.com/himansudev/tableViewIssue_15_4_20_1.git
Now I have a solution for this problem but I believe its not a proper solution. So what I have done is as shown below
1) I have modified the button event handler, see below is the modified code. Please refer to the above code to identify the changes that I have made to this event handler
#IBAction func buttonAction(_ sender: Any) {
let indexPath = IndexPath(row: 0, section: 0)
tableView.reloadRows(at: [indexPath] , with: UITableView.RowAnimation.automatic)
}
2) Secondly I have added this extra piece of code , see below
override func viewDidLayoutSubviews() {
print("viewDidLayoutSubviews")
let indexPath = IndexPath(row: 0, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
if cell.viewHeightConstraint.constant == 75 {
cell.viewHeightConstraint.constant = 10
}
else{
cell.viewHeightConstraint.constant = 75
}
}
Find the source code after changes below
https://github.com/himansudev/tableViewSolution_15_4_20_1.git
Now after doing these two changes it is working (but sometimes it doesn't work when I tap on the button rapidly many times) but the problem is the viewDidLayoutSubviews() is not getting called but when I comment it than the cell is not working as expected .
SO I want to know why is it behaving that way???
First of all you need to add also the UITableViewDelegate to your ViewController and a var like this:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var cellHeight: CGFloat = 75
and the heightForRow function which will return the right Height:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeight
}
Then on your button action:
#IBAction func buttonAction(_ sender: Any) {
if cellHeight == 75 {
cellHeight = 10
}
else{
cellHeight = 75
}
tableView.reloadData()
}
Also remove the constraint viewHeightConstraint because you do not need it.

Access custom UITableViewCell from random func in swift 3

I have a custom UITableViewCell, where i am trying to change the cell.indicatorLabel background color from a func, but i do not know how to access the cell from that func
class mainCell: UITableViewCell {
#IBOutlet weak var barcodeLabel: UILabel!
#IBOutlet weak var indicatorLabel: UILabel!
}
and i have a func called
func scan() {}
my cellForRowAt looks like this
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? mainCell
cell?.barcodeLabel.text = barcodeArray[indexPath.row].Barcode
cell?.indicatorLabel.text = barcodeArray[indexPath.row].Indicator
return cell!
}
i like to change the background color of the label from my func, anyone who can help with this?

When trying to display images from an array on a table view, I am receiving an the error "exc_bad_instruction (code=EXC_I386_INVOP, subcode=0x0"

To create an "Events" page of an app, I am using table view to list an image, name, and details of the event. You will be able to select an event, as well as add one.
I am currently populating my table with data stored as an array, however when I try to place the images data, I return an error in this line of code:
cell.photo.image = images[indexPath.row]
Can anyone help figure out why I am returning this error?
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
var names = ["BTown Diner", "Dunnkirk", "Chocolate Mousse", "Lil Wayne", "Annie", "Campus Squad Social"]
var details = ["Free drink with meal after 12 AM", "LADIES drink free", "10% off all ice cream!", "Lil 500 concert", "an IU Theater Production", "Bring your Squad to the Campus Squad Social"]
var images = [UIImage(named: "btown_diner"), UIImage(named: "dunnkirk"), UIImage(named: "choco_moose"), UIImage(named: "lilwayne"), UIImage(named: " ")]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
cell.name.text = names[indexPath.row]
cell.detail.text = details[indexPath.row]
cell.photo.image = images[indexPath.row]
return cell
}
}
Additionally, here is my CustomCell.swift file
import UIKit
class CustomCell: UITableViewCell {
#IBOutlet var photo: UIImageView!
#IBOutlet var name: UILabel!
#IBOutlet var detail: 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
}
}
Your variable names has a count of 6.
Your table will have 6 rows from return names.count. However, your variable images has a count of 5.
I think when your function tableView:cellForRowAtIndexPath gets called with indexPath equal to 5, your images array is out of bounds.

getting the index path of a cell inside UITableViewCell in swift

could anyone tell me how to get the index of a cell inside its class which is uitableViewCell more specifically , inside an action function of UISwitch .
I did the following..
var cell = sender.superview?.superview as UITableViewCell
var table: UITableView = cell.superview as UITableView
let indexPath = table.indexPathForCell(cell)
but then it crashes.
what is the solution ?
Try this:
Assuming you have a UISwitch *cellSwitch object in cell custom class
In cellForRowAtIndexPath:
cell.cellSwitch.tag = indexPath.row
In IBAction for this switch:
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
You don't want to know the index path of the cell inside of the cell. The index path is an implementation detail of the UITableViewController. The cell should be an independent object.
What you really want to do is to assign an action to run when your switch is changed.
class MySwitchCell: UITableViewCell {
#IBOutlet weak var switchCellLabel: UILabel!
#IBOutlet weak var mySwitch: UISwitch!
//Declare an action to be run
var action: ((sender: UISwitch) -> Void)?
//then run it
#IBAction func switchAction(sender: UISwitch) {
action?(sender: sender)
}
}
Then give the action something to do when you configure the cell.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("SwitchCell", forIndexPath: indexPath) as! MySwitchCell
cell.switchCellLabel.text = items[indexPath.row]
cell.mySwitch.on = NSUserDefaults.standardUserDefaults().boolForKey(items[indexPath.row])
cell.action = { [weak self] sender in
if let tableViewController = self {
NSUserDefaults.standardUserDefaults().setBool(sender.on, forKey: tableViewController.items[indexPath.row]) }
}
return cell
}
For example this one sets a bool in the NSUserDefaults based on the state of that switch.
You can checkout the whole sample project from https://github.com/regnerjr/SimpleCellSwitchAction

Repeating values in Stepper inside TableViewCell when scrolling

Stepper problem when cells need scroll.
My_TableViewCell.swift
import UIKit
class My_TableViewCell: UITableViewCell {
#IBOutlet weak var My_Label1: UILabel!
#IBOutlet weak var My_Label2: UILabel!
#IBOutlet weak var My_Stepper: UIStepper!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
...
My_TableViewController.swift
import UIKit
var My_Ids = ["C01","C02","C03","C04","C05","C06","C07","C08","C09","C10"]
var My_Values = ["0","0","0","0","0","0","0","0","0","0"]
class My_TableViewController: UITableViewController {
#IBAction func My_Stepper(sender: AnyObject) {
let point = sender.convertPoint(CGPointZero, toView: tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)!
let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! My_TableViewCell
cell.My_Label2.text = "\(Int(cell.My_Stepper.value))"
}
...
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return My_Ids.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell =
self.tableView.dequeueReusableCellWithIdentifier(
"My_TableCell", forIndexPath: indexPath)
as! My_TableViewCell
let row = indexPath.row
cell.My_Label1.text = My_Ids[row]
cell.My_Label2.text = "\(Int(cell.My_Stepper.value))"
return cell
}
...
When all cells fit in a "page" the Stepper works well but if the cells are resized and you need scroll the tableview the values are repeated in other cells.
If you alter the value on the cells C06 and C07 this will to reflect C01 and C02 cells and vice-versa.
Please view this image showing the snapshots with the errors
UITableViewController intentionally reuses cells as an optimization. You need to clear the old cell settings as part of your solution. Add a prepareForReuse method to your My_TableViewCell class.
You do this:
- (void) prepareForReuse
{
[super prepareForReuse];
// clear previous cell settings
}
Additional Notes:
recommend against calling cellForRowAtIndexPath directly. See this thread.
recommend you use Pascal casing for class names: Use MyTableViewCell instead of My_TableViewCell.

Resources