I am trying the to reload the tableview whenever the didset is countRow is called. It has never worked.
I have tried guard and if let in the didset, it has never work out.
I realised it is calling another object of tableview. it is very weird,
import UIKit
class ViewController:UIViewController, UITableViewDelegate, UITableViewDataSource {
// Global Variable
var tableView: UITableView!
var tableView2 : UITableView!
var countRow : Int = 0 {
didSet{
//if let tableview == tableview
guard tableView2 == tableView else
{
tableView2 = UITableView(frame: self.view.bounds)
tableView2.delegate = self
tableView2.dataSource = self
self.tableView2.reloadData()
self.tableView.reloadData()
print ("3countRow: \(countRow)")
return
}
self.tableView2.reloadData()
self.tableView.reloadData()
print ("2countRow: \(countRow)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: self.view.bounds)
tableView.delegate = self
tableView.dataSource = self
self.view.addSubview(tableView)
tableView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
tableView.register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
tableView.register(AppCell.self, forCellReuseIdentifier: "NormalCell")
tableView.register(appDays.self, forCellReuseIdentifier: "textField")
tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print (countRow)
return 5 + countRow
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "NormalCell", for: indexPath) as! AppCell
cell.backgroundColor = UIColor.groupTableViewBackground
return cell
}
if indexPath.row == 1 || indexPath.row == 2
{
var cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.backgroundColor = UIColor.groupTableViewBackground
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "textField", for: indexPath) as! appDays
cell.backgroundColor = UIColor.groupTableViewBackground
return cell
}
}
countrow will be printed in the program
You never set countRow to a value. You only add 5 + countRow which does not mean you set 5 in countRow.
didSet is called immediately after the new value is stored. Swift official documentation
Related
I tried using the simulator and real phone, I still get the same error.
ERROR: Thread 1: Exception: Application tried to present a nil modal view controller on target
Here's the complete ViewController. Please see the codes below.
import UIKit
import MessageUI
class CellClass: UITableViewCell {
}
class ContactUsViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBOutlet weak var messageField: UITextField!
#IBOutlet weak var subjectField: UIButton!
let transparentView = UIView()
let tableView = UITableView()
var selectedButton = UIButton()
var dataSource = [String]()
var MFMailComposeResultCancelled = MFMailComposeResult(rawValue: 0)
var MFMailComposeResultFailed = MFMailComposeResult(rawValue: 0)
var MFMailComposeResultSaved = MFMailComposeResult(rawValue: 0)
var MFMailComposeResultSent = MFMailComposeResult(rawValue: 0)
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(CellClass.self, forCellReuseIdentifier: "Cell")
}
func addTransparentView(frames: CGRect) {
let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
transparentView.frame = window?.frame ?? self.view.frame
self.view.addSubview(transparentView)
tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height, width: frames.width, height: 0)
self.view.addSubview(tableView)
tableView.layer.cornerRadius = 5
transparentView.backgroundColor = UIColor.black.withAlphaComponent(0.9)
tableView.reloadData()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(removeTransparentView))
transparentView.addGestureRecognizer(tapGesture)
transparentView.alpha = 0
UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: {self.transparentView.alpha = 0.5
self.tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height + 5, width: frames.width, height: CGFloat(self.dataSource.count * 50))
}, completion: nil)
}
#IBAction func subjectList(_ sender: Any) {
dataSource = [" General Inquiries", " Purchase STL File"," Purchase an Eternity Band Ring", " Inquire about Measurements"]
selectedButton = subjectField
addTransparentView(frames: subjectField.frame)
}
#objc func removeTransparentView() {
let frames = selectedButton.frame
UIView.animate(withDuration: 0.4, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .curveEaseInOut, animations: { self.transparentView.alpha = 0
self.tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height, width: frames.width, height: 0)
}, completion: nil)
}
#IBAction func sendTapped(_ sender: Any) {
let toCS = ["info#ezbandcalculator.com"]
let mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setToRecipients(toCS)
mc.setSubject(selectedButton.currentTitle!)
mc.setMessageBody("Message: \(String(describing: messageField?.text))", isHTML: false)
self.present(mc, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
switch result.rawValue {
case MFMailComposeResultCancelled!.rawValue:
print ("Cancelled")
case MFMailComposeResultFailed!.rawValue:
print ("Failed")
case MFMailComposeResultSaved!.rawValue:
print ("Saved")
case MFMailComposeResultSent!.rawValue:
print ("Sent")
default:
break
}
controller.dismiss(animated: true, completion: nil)
}
#IBAction func dismissKeyboard(_ sender: Any) {
self.resignFirstResponder()
}
}
extension ContactUsViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = dataSource[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedButton.setTitle(dataSource[indexPath.row], for: .normal)
removeTransparentView()
}
}
You may want to check whether your current device can send mail or not before presenting.
if MFMailComposeViewController.canSendMail() {
// present
}
Refer: https://developer.apple.com/documentation/messageui/mfmailcomposeviewcontroller/1616879-cansendmail
I have embed a UISwitch on a UITableView cell.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if self.users.count > 0 {
let eachPost = self.users[indexPath.row]
let postDate = (eachPost.date as? String) ?? ""
let postTitle = (eachPost.title as? String) ?? ""
cell.detailTextLabel?.text = postDate
cell.textLabel?.text = postTitle
}
if cell.accessoryView == nil{
let switchView : UISwitch = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
cell.accessoryView = switchView
}
return cell
}
My table has 30 rows. When I select a switch on the visible cells and then scroll down, on the cells from the bottom of the list the switch is selected by default. What can I do to have correct selections for my list?
My solution without creating a custom class:
class MyTableViewController: UITableViewController {
var users: [[String: Any]] = [[String: Any]]()
// This array is used for storring the state for switch from each cell. Otherwise when the cell is reused the state is displayed incorrectly
var switchArray = [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
self.users = result
for _ in 0 ..< self.users.count {
self.switchArray.append(false)
}
self.tableView?.reloadData()
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let eachPost = self.users[indexPath.row]
let postTitle = (eachPost.title as? String) ?? ""
cell.textLabel?.text = postTitle
let switchView : UISwitch = UISwitch(frame: .zero)
switchView.isOn = self.switchArray[indexPath.row]
cell.accessoryView = switchView
return cell}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
self.switchArray[indexPath.row] = true
let switchView : UISwitch = (tableView.cellForRow(at: indexPath)?.accessoryView) as! UISwitch;
switchView.isOn = true
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
self.switchArray[indexPath.row] = false
let switchView : UISwitch = (tableView.cellForRow(at: indexPath)?.accessoryView) as! UISwitch;
switchView.isOn = false
}
Note: Multiple selection has to be enabled
I'm using two table view in one view controller to populate my different data. All the other delegates methods are working fine but didselect method is not performing an action neither its printing any value in console. I hae checked through story board also all the things looks fine and i have set its delegate and datasources methods also but still it isn't working. Searched a lot from net but still unsuccessful in it. My code is this,
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
self.searchBar.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
dishDetailTableView.delegate = self
dishDetailTableView.dataSource = self
self.addOnTableView.allowsMultipleSelection = true
addOnTableView.delegate = self
addOnTableView.dataSource = self
dishDetailTableView.reloadData()
sectionArray = [String(MenuService.instance.subCategoryModelInstance[0].sub_categoryName)]
print(sectionArray)
cancelBtn.cornerButton()
cancelBtn.layer.borderColor = #colorLiteral(red: 1, green: 0, blue: 0.03742904276, alpha: 1)
cancelBtn.layer.borderWidth = 1.5
nextBtn.layer.borderColor = #colorLiteral(red: 0.09759091236, green: 0.5779017098, blue: 1, alpha: 1)
nextBtn.layer.borderWidth = 1.5
nextBtn.cornerButton()
menuTypeLbl.layer.cornerRadius = 5
addOnView.borderView(view: addOnView)
addOnView.isHidden = true
shadowView.isHidden = true
}
extension DishDetailViewController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if tableView == dishDetailTableView {
count = MenuService.instance.subCategoryItemModelInstance.count
}
if (tableView == addOnTableView) {
count = AddOnService.instance.AddOnModelInstance.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell:UITableViewCell?
if tableView == dishDetailTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! MenuDetailTableViewCell
cell.titleLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemName
cell.descriptionLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemdescription
cell.priceLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemprice
cell.backgroundColor = UIColor.clear
cell.delegate = self
cell.selectionStyle = .none
return cell
}
if tableView == addOnTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AddOnTableViewCell
cell.addOnLbl.text = AddOnService.instance.AddOnModelInstance[indexPath.row].itemName
print(cell.addOnLbl?.text! as Any)
return cell
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == dishDetailTableView{
print("Hi")
dishDetailTableView.reloadData()
}
if tableView == addOnTableView {
print("Hello")
addOnTableView.reloadData()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var count : Int?
if tableView == dishDetailTableView{
count = 120
}
if tableView == addOnTableView{
count = 60
}
return CGFloat(count!)
}
}
How can i perform any action on cell?
I have followed a tutorial of Vea software (https://www.veasoftware.com/tutorials/2015/6/27/uisearchcontroller-in-swift-xcode-7-ios-9-tutorial) to create a table view with search bar on xcode 7, ios 9. Now I need to select multiple rows from the table view by adding a checkmark on each row when selected, the problem is that when I use the search bar the checkmarks don't match the rows anymore..
Here's my code:
class SportSearchTableViewController: UITableViewController, UISearchResultsUpdating {
let appleProducts = ["Mac","iPhone","Apple Watch","iPad"]
var filteredAppleProducts = [String]()
var resultSearchController = UISearchController()
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath,animated: true)
let selectedRow = tableView.cellForRowAtIndexPath(indexPath)!
if selectedRow.accessoryType == UITableViewCellAccessoryType.None {
selectedRow.accessoryType = UITableViewCellAccessoryType.Checkmark
selectedRow.tintColor = UIColor.blueColor()
} else {
selectedRow.accessoryType = UITableViewCellAccessoryType.None
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.resultSearchController.active)
{
return self.filteredAppleProducts.count
}
else
{
return self.appleProducts.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?
if (self.resultSearchController.active)
{
cell!.textLabel?.text = self.filteredAppleProducts[indexPath.row]
return cell!
}
else
{
cell!.textLabel?.text = self.appleProducts[indexPath.row]
return cell!
}
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
self.filteredAppleProducts.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.sportsList as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredAppleProducts = array as! [String]
self.tableView.reloadData()
}
Does anyone know how to fix that?
I need horizontal images in collectionview, which is inside every tableview cell. The problem I am facing is tableview gets loaded easily, but collectionview doesn't get loaded before tableview cells, because tableview loads very quickly, and hence the array for collectionview gets changed.
The code I am using for the whole view, is -
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,NSURLConnectionDelegate {
#IBOutlet var tbl_data: UITableView!
var mutableData: NSMutableData!
var response: NSURLResponse!
var connection: NSURLConnection!
var thedata:NSArray!
var ary_OF_collectionView:NSArray!
override func viewDidLoad() {
super.viewDidLoad()
connection_GetPeopleList()
thedata = NSArray()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return thedata.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
//println("INdex===\(indexPath.row)")
let cell = tableView.dequeueReusableCellWithIdentifier("dTableViewCell", forIndexPath: indexPath) as! dTableViewCell
var c_snippet:String = ""
if let checkC_snip:AnyObject = thedata.objectAtIndex(indexPath.row).valueForKey("c_snippet")
{
c_snippet = checkC_snip as! String
}
var getImageArray:NSArray = (thedata.objectAtIndex(indexPath.row).valueForKey("images") as? NSArray)!
cell.lbl_like.text = c_snippet
cell.co_v.tag = indexPath.row
if(getImageArray.count > 0)
{
if(getImageArray.count == 1)
{
var getimagePath:String = getImageArray.objectAtIndex(0) as! String
if(!getimagePath.isEmpty)
{
ary_OF_collectionView = getImageArray
}else
{
ary_OF_collectionView = NSArray()
}
}else
{
ary_OF_collectionView = getImageArray
}
}else
{
ary_OF_collectionView = NSArray()
}
cell.co_v.dataSource = self
cell.co_v.delegate = self
cell.co_v.reloadData()
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return ary_OF_collectionView.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell
var getImageUrl:String! = ary_OF_collectionView.objectAtIndex(indexPath.row) as! String
println(getImageUrl)
// This is image loader From == https://github.com/natelyman/SwiftImageLoader
ImageLoader.sharedLoader.imageForUrl(getImageUrl, completionHandler:{(image: UIImage?, url: String) in
cell.img.image = image
})
//cell.img.image = UIImage(named: ) as UIImage!
return cell
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
println("INinininin===\(indexPath.row)")
// var cell:dTableViewCell = cell as! dTableViewCell
// [cell setCollectionViewDataSourceDelegate:self index:indexPath.row];
}
func scrollViewDidScroll(scrollView: UIScrollView) {
println(scrollView)
// println("INinininin===\(scrollView.tag)")
}
func connection_GetPeopleList()
{
let urlPath: String = "http://carbonchase.com/v1.1/get_jives.php?user_id=3221128362&at=0&newsfeeds&count=10"
println("get_People List == \(urlPath)")
var escapedAddress = urlPath.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
var url: NSURL = NSURL(string: escapedAddress!)!
var request1: NSURLRequest = NSURLRequest(URL: url)
self.connection = NSURLConnection(request: request1, delegate: self, startImmediately: true);
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
self.response = response
self.mutableData = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
self.mutableData.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!)
{
if let jsonResult: NSArray = NSJSONSerialization.JSONObjectWithData(self.mutableData, options: nil, error:nil) as? NSArray {
thedata = jsonResult
self.tbl_data.reloadData();
self.tbl_data.delegate=self;
self.tbl_data.dataSource=self;
}
}
func connection(connection: NSURLConnection, didFailWithError error: NSError) {
println("\(error)")
}
}// END
EDITED
CollectionView is not working