UITableView scrolls horizontally on iOS7 when loading Cell from Nib? - ios

I created a UITableViewController subclass:
class RootTableViewController: UITableViewController {
private let cellIdentifier = "MyCell2"
private let cellNibName = "MyCell2"
private var itemList: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<1000 {
itemList.append("T\(i)")
}
let nib = UINib(nibName: cellNibName, bundle: nil)
self.tableView.registerNib(nib, forCellReuseIdentifier: cellIdentifier)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemList.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MyCell2
return cell
}
MyCell2 is a subclass of UITableViewCell:
class MyCell2: UITableViewCell {
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
}
}
MyCell2.xib contains a UIButton in its ContentView. The Identifier the UITableViewCell is set to MyCell2 and the Class is set to MyCell2.
When I run the app on iOS8 everything works fine. There is no horizontal scrolling. When I run the app on iOS7 horizontal scrolling takes place:
How can I prevent horizontal scrolling of the table in iOS7?
Edit: My UITableView xib configuration is:

Do you have this UITableView configuration in your xib file/storyboard?

Related

UITableViewCell with embedded vertical Stack View setup with auto layout and dynamic height

I am trying to make a dynamic cell using stack view embedded in a cell so when items are added to the cell the height of cell adapt to the height of the stack view but not getting the expected results meaning I get ambitious constraints.
Here is how to set the setup is.I have a cell with an embedded stack view:
class MyCell: UITableViewCell {
override var reuseIdentifier: String? {
return "cell"
}
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
}
#IBOutlet public weak var stack: UIStackView?
}
This is how the nib looks like:
in table view code I have the following:
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MyCell
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
for _ in 0...10 {
let view = MyView()
cell.stack!.addArrangedSubview(view)
}
}
return cell
}
where MyView is:
class MyView: UIView {
override var intrinsicContentSize: CGSize {
setContentHuggingPriority(.defaultHigh, for: .vertical)
backgroundColor = .blue
return CGSize(width: 50, height: 50)
}
}
It seems the mistake was coming from anchoring the bottom of stack view to the bottom of the content view, instead one should anchor the bottom of the last view on the stack to the bottom of the contentView.

How to set UIImageView.image property in UITableViewCell

I am having a problem trying to show an array of images on each cell, for a tableview.
I have a separate TableViewCell Swift file where I have a UIImage on the cell linked up. The outlet is named: CellVenueImage
For some reason when I try to implement the image on my TableView view controller, I get an error that says: Value of type 'TableViewCell' has no member 'CellVenueImage'
Here is the line in which that happens:
cell.CellVenueImage.image = imagename
Using Swift 3.
Here is the code for the TableView:
import UIKit
class VenueTableViewController: UITableViewController {
let VenueImageList = ["1970s.png","1980s.png","1990s.png"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return VenueImageList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! TableViewCell
let imagename = UIImage(named: VenueImageList[indexPath.row])
cell.CellVenueImage.image = imagename
return cell
}
TableViewCell code:
import UIKit
class VenuesTableViewCell: UITableViewCell {
#IBOutlet weak var CellVenueImage: UIImageView!
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
}
The mistake is, that you're not using your created TableViewCell Subclass, you are using a regular UITableViewCell.
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! TableViewCell
You need to cast it as your UITableViewCell subclass.
If it is called "VenuesTableViewCell", for example: class VenuesTableViewCell: UITableViewCell {, then cast it as VenuesTableViewCell.
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! VenuesTableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "VenueCell", for: indexPath) as! VenuesTableViewCell

Swift / How to populate UITableViewCells

I have a controller with a Table View on it. Have defined my cells in a view and then I bind it to the table view. (Please excuse the terminology). App builds and runs fine but none of the labels defined in the cell show anything. Entire table is blank except for the cell separators. I've followed numerous tutorials and searched SO extensively for reasons, how to create (Create a Table View - Apple docs), settings to check, all with the same results. I've also tried cleaning, restarting Xcode, etc. This is Xcode 8/Swift 3.
The view controller has a table view and I register the cell class like so in the viewDidLoad
self.tableView.registerCellClass(MenuTableViewCell.self)
UITableViewDataSource code
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menusItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MenuTableViewCell.identifier, for: indexPath) as! MenuTableViewCell
let item = menusItems[indexPath.row]
cell.setData(item)
return cell
}
menuItems is an array of a struct I have that is created before anything else is done
BaseTableViewCell
open class BaseTableViewCell: UITableViewCell {
class var identifier: String { return String.className(self) }
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setup()
}
open override func awakeFromNib() {
}
open func setup() {
}
open override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
open class func height() -> CGFloat {
return 48
}
open func setData(_ data: Any?) {
if let menuText = data as? String {
self.textLabel?.text = menuText
}
if let menuImage = data as? UIImage {
self.imageView?.image = menuImage
}
}
}
Table View Cell code - inherits the BaseTableViewCell
class MenuTableViewCell: BaseTableViewCell {
//MARK: Properties
#IBOutlet weak var name: UILabel!
#IBOutlet weak var icon: UIImageView!
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
}
override func setData(_ data: Any?) {
if let data = data as? MenuTableViewCellData {
NSLog("menu name - %#", data.text)
self.icon?.image = data.image
self.name?.text = data.text
}
}
}
All menu names are written to the debug area so the code is being executed.
I don't know if there is hook that is missing or if something else. Please let me know if anything further is also needed. Any help is appreciated.
Screenshots showing IBOutlets connected
Here is the delegate and data source from the controller
extension LeftViewController : UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return MenuTableViewCell.height()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let menu = LeftMenu(rawValue: indexPath.row) {
self.changeViewController(menu)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if self.tableView == scrollView {
}
}
}
extension LeftViewController : UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menusItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MenuTableViewCell.identifier, for: indexPath) as! MenuTableViewCell
let item = menusItems[indexPath.row]
cell.setData(item)
return cell
}
}
Thanks everyone for your help. I was able to get it working. I removed the XIB file, created the layout in the view and then wired it up from there (followed here for how to).
Verify that you've connected the IBOutlets for name and icon in MenuTableViewCell. Assuming what you say is true, that the NSLog in setData is called, chances are you haven't connected the IBOutlets for the table view cell subclass.
You may have 0-height rows. I see a height method in there - what is calling it? Do you have an implementation of
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
somewhere?
Are you setting the table view's rowHeight?
Can you check whether name and icon have proper constraints

TableView cellForRowAtIndexPath is never called (iOS, Swift)

I have a problem with creating a table view in UITableViewController. I have tried everything I have found, reuseIdentifier is set correctly, number of rows returns non-zero number and height is set in storyboard. Only the cellForRowAtIndexPath is not called, other table functions runs correctly.
Here is the code:
TableViewController:
import UIKit
import Photos
class CropTableViewController: UITableViewController {
var photos = [Photo]()
var photoAssets = [PHAsset]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return photos.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CropTableViewCell
let photo = photos[indexPath.row]
cell.photoImageView.image = photo.photo
return cell
}
}
TableViewCell:
import UIKit
class CropTableViewCell: UITableViewCell {
#IBOutlet weak var photoImageView: UIImageView!
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
}
}
The photos array is empty, so photos.count is zero, so numberOfRowsInSection returns 0, so the runtime knows that there are no cells and that there is no need to call cellForRowAtIndexPath.

Thousands of UITableViewCellSeperatorView in UITableView with custom cell

Since I use xCode 6 beta 5 UITableViews with nib files for custom cells shows only a small stripe of the cell on the left and the rest is grey. When I open up the View Debugger it says that there are thousands of _UITableViewCellSeperatorViews in my TableView.
Here is the class of the TableViewController
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "TestTableViewCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "newTestCell")
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("newTestCell", forIndexPath: indexPath) as TestTableViewCell
cell.loadData("Test")
return cell
}
Here is the class of the cell:
#IBOutlet weak var someLabel: UILabel!
func loadData(text: String) {
someLabel.text = text
}
Now I've got a picture of the TableView in the View Debugger:
This is indeed puzzling. Here is how I fixed it: just after registering the nib add
tableView.rowHeight = 44 // or whatever

Resources