Remove right shadow of UITableViewCell on initial load - ios

I am trying to create a card type layout and have used many answers here to get to my current solution. I am using Swift 2 and XCode 7.3.1.
First App Load
After pull to refresh
The UITableViewCell code is:
func addShadow() {
cardView.layer.shadowPath = UIBezierPath(rect: cardView.bounds).CGPath
cardView.layer.shadowOpacity = 0.7
cardView.layer.shadowOffset = CGSizeZero
cardView.layer.shadowRadius = 2
cardView.layer.masksToBounds = false
}
override func layoutSubviews() {
addShadow()
}
Why does the cell only look correct after a pull to refresh and have the extra shadow to the right beforehand?
EDIT:
I'm added the TableViewController as well
class BusinessTableViewController: PFQueryTableViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController!.navigationBar.translucent = false
navigationController?.toolbar.translucent = false
configureTable()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configureTable() {
tableView.tableFooterView = UIView(frame: CGRectZero)
tableView.backgroundColor = Utility.tableBackgroundColor
}
override func queryForTable() -> PFQuery {
let query = PFQuery(className: "Business")
query.cachePolicy = .NetworkElseCache
query.orderByAscending("createdAt")
return query
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cell = tableView.dequeueReusableCellWithIdentifier("businessCell", forIndexPath: indexPath) as! BusinessCell
cell.layoutIfNeeded()
let business = object as! Business
cell.nameLabel.text = business.name
var categoryString = ""
for cat in business.categories {
categoryString += cat
if cat != business.categories.last {
categoryString += ", "
}
}
// Image setup
if cell.mainImageView.layer.cornerRadius != 3 {
cell.mainImageView.layer.cornerRadius = 3
cell.mainImageView.clipsToBounds = true
cell.mainImageView.layer.frame = CGRectInset(cell.mainImageView.layer.frame, 60, 60)
cell.mainImageView.layer.borderColor = UIColor.purpleColor().CGColor
cell.mainImageView.layer.borderWidth = 2.0
}
let imageFile = business.displayImage
cell.mainImageView.file = imageFile
cell.mainImageView.loadInBackground()
// Button steup
let defaultAttributes = [
NSFontAttributeName: UIFont.fontAwesomeOfSize(15),
NSForegroundColorAttributeName: UIColor.grayColor()]
let activeAttributes = [
NSFontAttributeName: UIFont.fontAwesomeOfSize(15),
NSForegroundColorAttributeName: UIColor.blueColor()]
cell.bookmarkButton.setTitleTextAttributes(defaultAttributes, forState: .Normal)
cell.bookmarkButton.title = "\(String.fontAwesomeIconWithName(.BookmarkO)) Bookmark"
let bookmarkQuery = PFQuery(className: "Bookmark")
bookmarkQuery.whereKey("business", equalTo: business)
bookmarkQuery.whereKey("user", equalTo: User.currentUser()!)
bookmarkQuery.cachePolicy = .NetworkElseCache
bookmarkQuery.countObjectsInBackgroundWithBlock { (count, error) in
if error == nil && count > 0 {
cell.bookmarkButton.setTitleTextAttributes(activeAttributes, forState: .Normal)
cell.bookmarkButton.title = "\(String.fontAwesomeIconWithName(.Bookmark)) Bookmark"
}
}
cell.phoneButton.setTitleTextAttributes(defaultAttributes, forState: .Normal)
cell.phoneButton.title = "\(String.fontAwesomeIconWithName(.Phone)) Call"
if business.phone == "" {
cell.phoneButton.enabled = false
}
cell.reviewButton.setTitleTextAttributes(defaultAttributes, forState: .Normal)
cell.reviewButton.title = "\(String.fontAwesomeIconWithName(.MapMarker)) Directions"
return cell
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row + 1 > self.objects?.count {
return 44
}
let height = super.tableView(tableView, heightForRowAtIndexPath: indexPath)
return height
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row >= self.objects?.count {
self.loadNextPage()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
return
}
//performSegueWithIdentifier("viewBusiness", sender: self)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

I figured this out for anyone who has the same issue:
override func awakeFromNib() {
super.awakeFromNib()
addShadow()
}
I added the code in awakeFromNib instead of layoutSubviews

Related

Random grey bar appears on top of ViewController in iOS (swift)

I am making an app currently and on the main screen where I load multiple items from Parse, I see a weird grey bar. I don't know where this bar came from as it does not show up on the storyboard and I don't know how to fix it. It never was a problem until it randomly recently showed up. Here is the code for that ViewController.
import UIKit
import Parse
import ParseUI
import Kingfisher
class HomeTableViewController: PFQueryTableViewController
{
override func viewDidLoad ()
{
super.viewDidLoad()
setTitle()
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.navigationBar.setHeight(0.0)
// self.tableView.scrollsToTop = true
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.bottom, animated: false)
// self.tableView.scrollToNearestSelectedRow(at: UITableViewScrollPosition.top, animated: true)
}
func setTitle()
{
var parentView = self.parent
while parent != nil
{
if let menu = parentView as? CucuMenuController
{
// menu.setTitleForLabel("Cucus")
menu.setTitleForLabel("")
break
}
parentView = parentView?.parent
}
}
var firstTime = true
var totalArticles = 0
let appDel = UIApplication.shared.delegate as! AppDelegate
required init!(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
setupHomefeed()
}
func setupHomefeed()
{
// This runs before didFinishLoadingWithOptions
self.parseClassName = "Article"
self.pullToRefreshEnabled = true
self.paginationEnabled = true
self.objectsPerPage = 10
self.loadingViewEnabled = true
}
override func objectsDidLoad(_ error: Error?)
{
super.objectsDidLoad(error)
if firstTime
{
firstTime = false
self.loadObjects()
self.tableView.reloadData()
}
else
{
PFObject.pinAll(inBackground: self.objects)
}
}
override func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
override func viewDidAppear(_ animated: Bool)
{
navigationController?.isNavigationBarHidden = false
if PFUser.current() == nil || PFUser.current()!["name"] == nil
{
let viewController = storyboard!.instantiateViewController(withIdentifier: "LoginController")
UIApplication.shared.keyWindow?.rootViewController = viewController
}
else if UserDefaults.standard.bool(forKey: "showDemo")
{
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
else
{
self.loadObjects()
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if self.objects!.count < totalArticles && self.objects!.count > 0
{
return self.objects!.count + 1
}
return self.objects!.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.row == self.objects?.count
{
return 70.0
}
else
{
return 221.5
}
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 0.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
if indexPath.row == self.objects!.count
{
return tableView.dequeueReusableCell(withIdentifier: "loadCell") as UITableViewCell!
}
if (indexPath.row > self.objects!.count)
{
return cell!
}
let imageView = cell?.viewWithTag(200) as! UIImageView
let titleText = cell?.viewWithTag(101) as! UILabel
let timeLabel = cell?.viewWithTag(102) as! UILabel
let newImage = cell?.viewWithTag(100) as! UIImageView
let diffImage = cell?.viewWithTag(300) as! UIImageView
let scoreLabel = cell?.viewWithTag(301) as! UILabel
let catLabel = cell?.viewWithTag(103) as! UILabel
let article = Article(parseData: self.objects![indexPath.row])
titleText.text = article.title
timeLabel.text = article.duration
catLabel.text = article.category.uppercased()
let hasRead = UserController.hasReadArticle(article.objectId)
newImage.isHidden = hasRead
if hasRead
{
let score = UserController.getScoreForArticle(article.objectId)
scoreLabel.text = NSString(format: "YOUR SCORE: %.0f", score) as String
var performance = "hard"
if score >= article.idealScore { performance = "easy" }
else if score * 2 >= article.idealScore { performance = "medium" }
diffImage.image = UIImage(named: performance + "ScoreTag")
if UserController.getPlayableForArticle(article.objectId) {
cell?.isUserInteractionEnabled = true
}
}
else
{
scoreLabel.text = NSString(format: "AVG. SCORE: %.0f", article.idealScore) as String
diffImage.image = UIImage(named: article.difficulty.lowercased() + "ScoreTag")
}
//Image
let resource = ImageResource(downloadURL: article.getImageURL(), cacheKey: article.objectId)
imageView.kf.setImage(with: resource)
UIHelper.addShadowToHomeCell((cell?.viewWithTag(1)!)!)
return cell!
}
var selectedIndex = -1
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.row == self.objects!.count
{
self.loadNextPage()
}
else
{
selectedIndex = indexPath.row
self.performSegue(withIdentifier: "detailSegue", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "detailSegue"
{
let dest = segue.destination as? ArticlePreviewViewController
if UserDefaults.standard.bool(forKey: "showDemo")
{
dest?.article = DemoArticle().article
}
else
{
dest?.article = Article(parseData: self.objects![selectedIndex])
}
}
NotificationCenter.default.post(name: Notification.Name(rawValue: "CUCU_START"), object: nil)
}
override func queryForTable() -> PFQuery<PFObject>
{
let q = PFQuery(className: "Article").whereKey("releaseDate", lessThanOrEqualTo: Date()).whereKey("validated", equalTo: true)
if firstTime
{
q.fromLocalDatastore()
}
else
{
let mods = PFQuery(className: "Question").whereKey("article", matchesQuery: q)
mods.findObjectsInBackground
{
(objects, err) -> Void in
PFObject.pinAll(inBackground: objects)
}
}
print(firstTime)
totalArticles = q.countObjects(nil)
q.order(byDescending: "createdAt")
return q
}
}
Here are a few images of what the problem looks like:
Edit 1:
As suggested in the comments, I even tried to debug view hierarchy but I don't know which element to delete to make the grey bar go away.
It looks like it might be your navigation bar. Have you tried using this:
self.navigationController?.setNavigationBarHidden(true, animated: true)
instead of the statement you have of:
self.navigationController?.isNavigationBarHidden = true
Update #2:
Actually, I just realized you have that in the viewDidLoad. Move that to viewWillAppear and I bet it will work.
Update #3:
Just to reflect the true fix here, the offending code was in the viewDidAppear:
navigationController?.isNavigationBarHidden = false

Search results are cut off when searching TableView

My search is working correctly except the display is not working as expected. When I am performing a search, the last search result is slightly cut off and the portion of the display is all gray. I would expect it to remain the same background color as the rows.. Any help would be appreciated.
EDIT:
import UIKit
import Foundation
// For search
extension MasterViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
}
class MasterViewController: UITableViewController {
let searchController = UISearchController(searchResultsController: nil)
var filteredFighters = [Fighter]()
var detailViewController: DetailViewController? = nil
var objects = [Any]()
// Creates array of fighters
var fighterArray = [Fighter]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem
if let split = self.splitViewController {
let controllers = split.viewControllers
self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
// Access all the data from JSON
let JR = JSONReceiver()
fighterArray = JR.populateFighterJSONArray()
// Search related
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
navigationItem.title = "UFC Champions"
self.navigationController?.navigationBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.titleTextAttributes = [ NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont(name: "Arial", size: 26)!]
}
// FOr search
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredFighters = fighterArray.filter { fighter in
return fighter.name.lowercased().contains(searchText.lowercased())
}
tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/* DONT BELIEVE THIS IS NEEDED - DO NOT SEE IN PROFESSORS CODE
func insertNewObject(_ sender: Any) {
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
} */
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Determines which row was selected (e.g. which fighters, say element 1 points to fighter1)
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
// let stud = StudentsArray[indexPath.row]
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
// Makes sure selected student points to the correct controller
controller.detailItem = fighter
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
return filteredFighters.count
}
return fighterArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
cell.textLabel!.text = fighter.name
cell.detailTextLabel?.text = fighter.record
cell.imageView?.image = UIImage(named: fighter.fighterImage)
self.tableView .sizeToFit()
// cell.detailTextLabel?.text = "fighterTest"
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
}

Issue in using Tabbarcontroller

i am using TabbarController with four tabbarItem. but my requirement is Tabbar is shown in Top on viewController so that is done.but issue is when adding dropdownview on viewcontroller Tabbar hides dropdown. please help me
My viewController Class Code
import UIKit
class TrendingVC: UIViewController,DropDownViewDelegate
{
#IBOutlet var btndropdown: UIButton!
var dropdown = DropDownView()
override func viewDidLoad() {
super.viewDidLoad()
dropdown = dropdown.initWithArrayData(["1111111111","222222222","3233333333","33333333333","1222333333"], cHeight: 30, tableviewHight: 150, tPaddingTop:0, tPaddingLeft: 0, tPaddingRight: 0, refView: btndropdown, tAnimation:AnimationType.GROW, openAnimationDuration: 0.5, closeAnimationDuration: 0.5, Dropdowncolor: UIColor.purpleColor(), DropdowntextColor: UIColor.whiteColor(), DropdowntextSize: 17) as! DropDownView
dropdown.delegate = self;
self.view.addSubview(dropdown.view);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func DropDownCellSelected(index: NSInteger)
{
print(index);
}
#IBAction func btndropdownclik(sender:UIButton!)
{
self.view.bringSubviewToFront(dropdown.view)
dropdown.OpenAnimation()
}
My Custom Dropdown Class Code Here
import UIKit
enum AnimationType
{
case BLENDIN
case GROW
case BOTH
}
protocol DropDownViewDelegate
{
func DropDownCellSelected(index:NSInteger) -> Void
}
class DropDownView: UIViewController,UITableViewDelegate,UITableViewDataSource
{
var arrDropDown = NSMutableArray()
var delegate: DropDownViewDelegate!
var OPENAnimationDuration,CLOSEAnimationDuration,DropdownViewTextsize,CellHight,DropDownHight,LeftMargin,RightMargin,TopMargin:CGFloat!
var refillview:UIView!
var DropdownViewColor,DropDownviewTextcolor:UIColor!
var animationType:AnimationType!
var tbl:UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
let refFrame:CGRect = refillview.frame;
tbl = UITableView();
tbl.frame = CGRectMake(0, 0, refFrame.size.width+RightMargin, (animationType == AnimationType.BOTH||animationType == AnimationType.BLENDIN) ?DropDownHight:1)
tbl.dataSource = self;
tbl.delegate = self;
//uiTableView.backgroundColor=[UIColor colorWithRed:15/255 green:41/255 blue:63/255 alpha:1];
tbl.backgroundColor = UIColor.clearColor()
self.view.addSubview(tbl)
self.view.hidden = true;
if (animationType == AnimationType.BOTH || animationType == AnimationType.BOTH)
{
self.view.alpha = 1;
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Tableview Methods
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrDropDown.count;
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cellidentifier:NSString = "CellId";
var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellidentifier as String)
if cell==nil
{
cell = UITableViewCell.init(style: UITableViewCellStyle.Default, reuseIdentifier: cellidentifier as String)
}
cell!.backgroundColor = UIColor.purpleColor();
cell!.textLabel?.text = arrDropDown.objectAtIndex(indexPath.row) as? String
cell!.selectionStyle = UITableViewCellSelectionStyle.None;
cell!.textLabel?.font = UIFont(name:"helvetica" , size: 20)
return cell!
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return CellHight;
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
self.CloseAnimation()
delegate.DropDownCellSelected(indexPath.row)
}
func OpenAnimation()
{
self.view.hidden = false
//var newCenter:CGPoint = CGPointMake(playAgainButton.center.x, playAgainButton.center.y + 200)
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(1.0)
tbl.frame = CGRectMake(tbl.frame.origin.x,tbl.frame.origin.y,tbl.frame.size.width, DropDownHight);
UIView.commitAnimations()
}
func CloseAnimation()
{
self.view.hidden = false;
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(1.0)
tbl.frame = CGRectMake(tbl.frame.origin.x,tbl.frame.origin.y,tbl.frame.size.width, 0);
UIView.commitAnimations()
}
func OpenAnimationWithRef()
{
}
func initWithArrayData(data:NSArray,cHeight:CGFloat,tableviewHight:CGFloat,tPaddingTop:CGFloat,tPaddingLeft:CGFloat,tPaddingRight:CGFloat,refView:UIView!,tAnimation:AnimationType,openAnimationDuration:CGFloat,closeAnimationDuration:CGFloat,Dropdowncolor:UIColor!,DropdowntextColor:UIColor!,DropdowntextSize:CGFloat) -> AnyObject
{
arrDropDown=data.mutableCopy() as! NSMutableArray;
CellHight = cHeight;
DropDownHight = tableviewHight;
TopMargin = tPaddingTop;
LeftMargin = tPaddingLeft;
RightMargin = tPaddingRight;
refillview = refView;
OPENAnimationDuration = openAnimationDuration;
CLOSEAnimationDuration = closeAnimationDuration;
animationType = tAnimation;
DropdownViewColor = Dropdowncolor;
DropDownviewTextcolor = DropdowntextColor;
DropdownViewTextsize = DropdowntextSize;
let reframe = refView.frame;
self.view.frame = CGRectMake(reframe.origin.x-LeftMargin, reframe.origin.y+reframe.size.height+TopMargin, reframe.size.width+RightMargin,DropDownHight);
self.view.layer.shadowColor = UIColor.clearColor().CGColor
self.view.layer.shadowOffset = CGSizeMake(5.0, 5.0)
self.view.layer.shadowOpacity = 1.0;
self.view.layer.shadowRadius = 5.0;
tbl.layer.cornerRadius = 5.0;
tbl.layer.borderWidth = 3.0;
tbl.layer.borderColor = UIColor.darkGrayColor().CGColor;
tbl.autoresizingMask = UIViewAutoresizing.FlexibleWidth;
return self
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

Are there some optional wrong here?

This is the code and the problem
There is no wrong when I did select one row before I add the function tableView(......didSelectRowatindexPath...)
So, I thought it's the root cause.
I hope somebody can help me because the wrong info was not so clear that I can understand it well.
What I want to do is change the BarItemName when I did select one row of my popover table.
SwitchA is a var in my popoverviewcontroller, it means which button is pressed.
When the button in "SecondVC" is pressed,it will pass a value to SwitchA and then the popoverviewcontroller can determine which datasource it should show.
PS:this is the popoverviewcontroller's code.
import UIKit
class PopOverView: UIViewController, UITableViewDataSource, UITableViewDelegate {
var SwitchA = 0
var ClassA = ["这个类型","那个类型","这个类型","那个类型","这个类型","那个类型","这个类型","那个类型","这个类型","那个类型"]
var TimeA = ["昨天","今天","明天","昨天","今天","明天"]
var TagA = ["动漫","音乐","游戏","音乐","游戏"]
#IBOutlet weak var TV: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
TV.dataSource = self
TV.delegate = self
self.preferredContentSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: 175)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
if SwitchA == 0 {
return ClassA.count
}
if SwitchA == 1 {
return TimeA.count
}
else {
return TagA.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
if SwitchA == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = ClassA[indexPath.row]
cell.separatorInset = UIEdgeInsetsZero
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
if SwitchA == 1 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = TimeA[indexPath.row]
cell.separatorInset = UIEdgeInsetsZero
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
else {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = TagA[indexPath.row]
cell.separatorInset = UIEdgeInsetsZero
cell.preservesSuperviewLayoutMargins = false
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 35.0
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
if SwitchA == 0 {
let VC = self.storyboard!.instantiateViewControllerWithIdentifier("SecondVC") as! XiaoNei_HuoDong
VC.ClassName.title = ClassA[indexPath.row]
}
if SwitchA == 1 {
let VC = self.storyboard!.instantiateViewControllerWithIdentifier("SecondVC") as! XiaoNei_HuoDong
VC.TimeName.title = TimeA[indexPath.row]
}
else {
let VC = self.storyboard!.instantiateViewControllerWithIdentifier("SecondVC") as! XiaoNei_HuoDong
VC.TagName.title = TagA[indexPath.row]
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
And this is the code of "SecondVC":
import UIKit
class XiaoNei_HuoDong: UIViewController,UITableViewDelegate,UITableViewDataSource, UIPopoverPresentationControllerDelegate{
#IBOutlet weak var TagName: UIBarButtonItem!
#IBOutlet weak var TimeName: UIBarButtonItem!
#IBOutlet weak var ClassName: UIBarButtonItem!
#IBOutlet weak var huodongTV: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
huodongTV.dataSource = self
huodongTV.delegate = self
huodongTV.showsVerticalScrollIndicator = false
let options = PullToRefreshOption()
options.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1)
options.indicatorColor = UIColor.blackColor()
huodongTV.addPullToRefresh(options: options, refreshCompletion: { [weak self] in
// some code
self!.huodongTV.reloadData()
self!.huodongTV.stopPullToRefresh()
})
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 3
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 1.0
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1.0
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.huodongTV.deselectRowAtIndexPath(indexPath, animated: false)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
if indexPath.row == 0 {
let cell:HuoDong_2 = tableView.dequeueReusableCellWithIdentifier("huodong2") as! HuoDong_2
cell.ClubB1.image = UIImage(named: "test")!
cell.ClubB2.image = UIImage(named: "test")!
cell.ClubS1.image = UIImage(named: "focus")!
cell.ClubS2.image = UIImage(named: "focus")!
cell.Tag1.image = UIImage(named: "更新")!
cell.Tag2.image = UIImage(named: "更新")!
cell.View1.image = UIImage(named: "view")!
cell.View2.image = UIImage(named: "view")!
cell.Newest.image = UIImage(named: "club rank")
return cell
}
else {
let cell:HuoDong = tableView.dequeueReusableCellWithIdentifier("huodong1") as! HuoDong
cell.ClubB1.image = UIImage(named: "test")!
cell.ClubB2.image = UIImage(named: "test")!
cell.ClubS1.image = UIImage(named: "focus")!
cell.ClubS2.image = UIImage(named: "focus")!
cell.Tag1.image = UIImage(named: "更新")!
cell.Tag2.image = UIImage(named: "更新")!
cell.View1.image = UIImage(named: "view")!
cell.View2.image = UIImage(named: "view")!
return cell
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath){
cell.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1)
UIView.animateWithDuration(0.25, animations: {
cell.layer.transform = CATransform3DMakeScale(1, 1, 1)
})
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == 0 {
return self.view.frame.width * 240.0 / 400.0
}
else {
return self.view.frame.width * 200.0 / 400.0
}
}
// MARK: - PopOverforsegue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Class1"{
let VC = segue.destinationViewController as! PopOverView
VC.SwitchA = 0
VC.modalPresentationStyle = UIModalPresentationStyle.Popover
VC.popoverPresentationController?.delegate = self
}
if segue.identifier == "Time1"{
let VC = segue.destinationViewController as! PopOverView
VC.SwitchA = 1
VC.modalPresentationStyle = UIModalPresentationStyle.Popover
VC.popoverPresentationController?.delegate = self
}
if segue.identifier == "Tag1"{
let VC = segue.destinationViewController as! PopOverView
VC.SwitchA = 2
VC.modalPresentationStyle = UIModalPresentationStyle.Popover
VC.popoverPresentationController?.delegate = self
}
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
I think problem is timing of initialize.
Try this:
SecondVC
var tagNameStr = ""
override func viewDidLoad() {
super.viewDidLoad()
TagName.title = tagNameStr // here
...
}
FirstVC
if SwitchA == 0 {
let VC = self.storyboard!.instantiateViewControllerWithIdentifier("SecondVC") as! XiaoNei_HuoDong
VC.tagNameStr = ClassA[indexPath.row]
}
Hope this helps!
UPDATE
This is sample code.
(ViewController -|segue|-> SecondViewController)
class ViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let vc = segue.destinationViewController as? SecondViewController {
vc.buttonTitle = "IOhYES"
}
}
}
class SecondViewController: UIViewController {
#IBOutlet weak var buttonItem: UIBarButtonItem!
var buttonTitle = ""
override func viewDidLoad() {
super.viewDidLoad()
buttonItem.title = buttonTitle
}
}
Please check IBOutlet connection.

Changing UITableViewController to UITableView crashes app

I have just changed from a UITableViewController to a UITableView, and everything is working fine, with the exception of the search bar, which when tapping on a key on the keyboard will crash the app with the error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier rideCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
I haven't changed anything in terms of the code. Someone suggested changing:
let cell = tableView.dequeueReusableCellWithIdentifier("rideCell", forIndexPath: indexPath) as! RideCell
to:
let cell = tableView.dequeueReusableCellWithIdentifier("rideCell") as! RideCell
but that didn't help at all.
Any suggestions?
EDIT:
Here is my code as requested:
class InitalViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
var rideName = ""
var parkPassed: Park!
var searchResults = NSArray()
var loadingIndicator = UIActivityIndicatorView()
var backgroundLabel = LabelWithInsets()
var refreshSpinner = UIRefreshControl()
func handleRefresh(refreshControl: UIRefreshControl) {
DataManager.sharedInstance.loadRides(parkPassed.name!.stringByReplacingOccurrencesOfString(" ", withString: ""))
refreshControl.endRefreshing()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
backgroundLabel.textAlignment = NSTextAlignment.Center
backgroundLabel.textColor = UIColorFromRGB(0x424242)
backgroundLabel.numberOfLines = 0
refreshSpinner.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshSpinner)
//refreshControl = refreshSpinner
self.tableView.tableHeaderView = searchBar
self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(searchBar.frame))
self.navigationController?.navigationBar.barTintColor = UIColorFromRGB(0x0096FF)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateTableView", name: "onRidesLoadedNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "displayError", name: "onRidesLoadFailedNotification", object: nil)
}
override func viewWillAppear(animated: Bool) {
if DataManager.sharedInstance.rideArray.count == 0 {
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
loadingIndicator.frame = CGRectMake((view.bounds.width / 2) - 25, (view.bounds.height / 2) - 50, 50, 50)
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
view.addSubview(loadingIndicator)
loadingIndicator.startAnimating()
backgroundLabel.text = "Loading rides..."
backgroundLabel.frame = CGRectMake(0, (view.bounds.height / 2) - 80, view.bounds.width, 30)
view.addSubview(backgroundLabel)
}
DataManager.sharedInstance.loadRides(parkPassed.name!.stringByReplacingOccurrencesOfString(" ", withString: ""))
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: false)
if NSUserDefaults.standardUserDefaults().arrayForKey("favourites") != nil {
let tempFavourites: NSArray = NSUserDefaults.standardUserDefaults().arrayForKey("favourites")!
favouritesArray = tempFavourites.mutableCopy() as! NSMutableArray
}
}
#IBAction func dismiss(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
func updateTableView() {
tableView.reloadData()
tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
loadingIndicator.removeFromSuperview()
backgroundLabel.removeFromSuperview()
}
func displayError() {
loadingIndicator.removeFromSuperview()
backgroundLabel.removeFromSuperview()
backgroundLabel.text = "Failed to load rides. Please check your internet connection."
backgroundLabel.frame = CGRectMake(0, (view.bounds.height / 2) - 80, view.bounds.width, 60)
view.addSubview(backgroundLabel)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
println(DataManager.sharedInstance.rideArray.count)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("rideCell", forIndexPath: indexPath) as! RideCell
var ride: Ride
if tableView == self.searchDisplayController?.searchResultsTableView {
ride = DataManager.sharedInstance.getRideByName(searchResults[indexPath.row].name)!
} else {
ride = DataManager.sharedInstance.rideAtLocation(indexPath.row)!
}
cell.rideNameLabel.text = ride.name
var dateSinceUpdate = NSDate().timeIntervalSinceDate(ride.updated!)
var secondsSinceUpdate = Int(dateSinceUpdate)
var timeSinceUpdate = printSecondsConvert(secondsSinceUpdate)
cell.updatedLabel.text = timeSinceUpdate
if ride.waitTime == "Closed" {
cell.waitTimeLabel.text = ride.waitTime!
cell.timeBackgroundView.backgroundColor = getColorFromNumber(80)
cell.waitTimeLabel.font = UIFont(name: "Avenir", size: 13)
} else {
cell.waitTimeLabel.text = "\(ride.waitTime!)m"
cell.timeBackgroundView.backgroundColor = getColorFromNumber(ride.waitTime!.toInt()!)
cell.waitTimeLabel.font = UIFont(name: "Avenir", size: 17)
}
AsyncImageLoader.sharedLoader().cancelLoadingURL(cell.rideImageView.imageURL)
cell.rideImageView.image = UIImage(named: "Unloaded")
cell.rideImageView.imageURL = NSURL(string: ride.rideImageSmall!)
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == self.searchDisplayController?.searchResultsTableView {
return searchResults.count
} else {
return DataManager.sharedInstance.rideArray.count
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let currentCell = tableView.cellForRowAtIndexPath(indexPath) as! RideCell!
rideName = currentCell.rideNameLabel.text!
performSegueWithIdentifier("showDetail", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showDetail") {
var viewController = segue.destinationViewController as! DetailViewController
viewController.currentRide = DataManager.sharedInstance.getRideByName(rideName)
viewController.parkPassed = parkPassed
}
}
func filterContentForSearchText(searchText: NSString) {
let resultPredicate = NSPredicate(format: "name contains[cd] %#", searchText) //Use either contains or beginswith
searchResults = (DataManager.sharedInstance.rideArray as NSArray).filteredArrayUsingPredicate(resultPredicate)
}
func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
self.filterContentForSearchText(searchString)
return true
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 71
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! RideCell
let favourite = UITableViewRowAction(style: .Normal, title: " ") { action, index in
if favouritesArray.containsObject(cell.rideNameLabel.text!) {
favouritesArray.removeObject(cell.rideNameLabel.text!)
} else {
favouritesArray.addObject(cell.rideNameLabel.text!)
}
NSUserDefaults.standardUserDefaults().setObject(favouritesArray, forKey: "favourites")
tableView.setEditing(false, animated: true)
}
if favouritesArray.containsObject(cell.rideNameLabel.text!) {
favourite.backgroundColor = UIColor(patternImage: UIImage(named: "Unfavourite")!)
} else {
favourite.backgroundColor = UIColor(patternImage: UIImage(named: "Favourite")!)
}
return [favourite]
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
}
Call next code in viewDidLoad method of view controller that contains your table view:
If you created RideCell in xib:
tableView.registerNib(UINib(nibName: "RideCell", bundle: nil),
forCellReuseIdentifier: "rideCell")
If you created RideCell in code:
tableView.registerClass(RideCell.self, forCellReuseIdentifier: "rideCell")
In your viewDidLoad you have to register the custom cell to your UITableView using this function:
func registerNib(_ nib: UINib,forCellReuseIdentifier identifier: String)

Resources