In order for table to load fast, need something like this, because the TableView is inside a UIViewController:
ViewController: UITableViewController, UIViewcontroller UITableViewDataSource, UITableViewDelegate {
But I get this error NSInternalInconsistencyException, reason:
[UITableViewController loadView] loaded the
"nbc-Kp-sp6-view-lBB-IH-x0z" nib but didn't get a UITableView.' This
is because it is a UIViewController.
I don't think you can get inherited from two controllers. You should probably delete getting inheritance from UITableViewController. Instead, use a UITableView alongside in your xib file(or you are using storyboard?). Then, connect to UITableViewDataSource and UITableViewDelegate just like the normal way you do when you handle UITableViewController.
Should be something like:
ViewController:UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableViewController!
// MARK: - UITableViewDataSource, UITableViewDelegate
...
}
Related
I have tableviewA in a viewController. I am using XIBs as cells for tableViewA. Inside those XIB, I have another tableViewB. Using delegate, I am trying to refresh tableViewB from viewController once I get data from server.
Code used are as follows. Don't know why tableViewB doesn’t get refreshed once data received from server
1.Define protocol
protocol tblRefresh: NSObject {
func refreshTbl()
}
2.ViewController
class HomeVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
weak var delegateTblRefresh : tblRefresh?
//tableViewA defined here
func getDataFromServer(){
// get data from server
self.delegateTblRefresh?.refreshTbl()
}
}
3.XIB as cell of tableViewA
class Challengers: UITableViewCell, UITableViewDelegate, UITableViewDataSource, tblRefresh {
#IBOutlet weak var tableViewB: UITableView!
let homeVC = HomeVC()
override func awakeFromNib() {
super.awakeFromNib()
homeVC.delegateTblRefresh = self
}
//tableViewB defined here
func refreshTbl() {
tableViewB.reloadData()
}
}
You are creating new instance of HomeVC which is not needed.
You don't need to write your own delegate method to refresh you tableView cell. Just reload the table when you get data from server. For example:
func getDataFromServer()
{
// get data from server
self.tableViewA.reloadData()
}
Or if you want to reload only a specific cell you can do this also.
As per title, when I try to print the data from viewDidLoad(), nothing is present in the array controller. But when I print the data from one of the tableview methods there is something in there. So is there a method I can use from the viewcontroller class to check when the tableview and it's data has finished loading?
class ViewController: NSViewController {
#IBOutlet var alarmArrayController: NSArrayController!
}
ArrayController's attributes in XCode for ViewController
ArrayController's Cocoa Bindings in XCode for ViewController
I have this block of code to print my array controller.
for object in alarmArrayController.arrangedObjects as! [Alarm] {
print(object)
alarmArrayController.removeObject(object)
}
It works within the following viewtable method
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?
but not within viewDidAppear() or viewDidLoad()
You could make your controller an NSFetchedResultsControllerDelegate. "A delegate protocol that describes the methods that will be called by the associated fetched results controller when the fetch results have changed." (Apple docs)
Have your class conform to the protocol:
class YourViewController: UITableViewController, NSFetchedResultsControllerDelegate
Set yourself as delegate when you create the data provider object:
provider.fetchedResultsControllerDelegate = self
Finally, create a class extension as below.
extension YourViewController {
func controllerDidChangeContent(_ controller:
NSFetchedResultsController<NSFetchRequestResult>) {
tableView.reloadData()
}
}
Okay. So I found my answer while I was updating my post.
What I realised was that at some point during the viewcontroller lifecycle, the data is loaded from core data to my array controller with Cocoa bindings. At what stage during this life cycle I had no idea. What also made things worse was I was looking at the docs for lifecycle of UIViewController not NSViewController.
NSViewController which appear to be different
UIViewController
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html
NSViewController
https://developer.apple.com/documentation/appkit/nsviewcontroller
As we can see there are addditional stages within viewDidAppear() for a NSViewController, these are
updateViewConstraints()
viewWillLayout()
viewDidLayout()
It seems the data isn't loaded until the method viewDidLayout() is called
I have a custom UIView with 3 tableviews, the tableviews are self-sizing depending on the content they have, and they a show a different nib when they are empty than when they have content. All of this is embedded in a scroll view and it's working already, my view scrolls and the tableviews display the content appropriately and they autosize properly, the scroll view's size is adjusting without problems either.
In two of the tableviews when the tableviews have items there are some buttons in the cell nib that I want to access along with the index of the cell clicked inside the View controller where I have defined the Table view.
Here in the pic I'm showing the tableViews each with one item, the Canastas tableView has just a delete item button and the Productos tableView has a delete item button and a stepper to increase or decrease the amount.
I found a solution involving delegates in StackOverflow
Get button click inside UI table view cell, which I implemented. But for some reason it isn't working and the code in the delegate method isn't being executed.
Here is my code:
CanastasViewCell
import UIKit
protocol CanastasViewCellDelegate: class {
func closeButtonTapped(at index: IndexPath)
}
class CanastasViewCell: UITableViewCell {
#IBOutlet weak var imagenProducto: UIImageView!
#IBOutlet weak var nombreProducto: UILabel!
#IBOutlet weak var descProducto: UILabel!
#IBOutlet weak var precioProducto: UILabel!
#IBOutlet weak var closeButton: UIButton!
weak var delegate: CanastasViewCellDelegate?
var indexPath: IndexPath!
override func awakeFromNib() {
super.awakeFromNib()
}
#IBAction func eliminarProducto(_ sender: AnyObject) {
self.delegate?.closeButtonTapped(at: indexPath)
}
}
CarritoViewController
import UIKit
class CarritoViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource, CanastasViewCellDelegate {
func closeButtonTapped(at index: IndexPath) {
print("Button tapped at index:\(index)")
}
It looks like you're not setting the delegate inside CarritoViewController. You'll want to make sure that you set cell.delegate = self inside func tableView(UITableView, cellForRowAt: IndexPath).
I use custom UIPresentationController to perform sequel with my own animation. In prepareForSegue:
myDestinationController.transitioningDelegate = DBViewControllerTransitioningDelegate()
myDestinationController.modalPresentationStyle = .Custom
This is mine DBViewControllerTransitioningDelegate:
class DBViewControllerTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
return DBOverlayPresentationController(presentedViewController: presented, presentingViewController: presenting)
}
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return DBTransitioningAnimator()
}
}
It is not working, because the methods are not called. But when I set:
myDestinationController.transitioningDelegate = self
and within my self controller add 2 methods from my DBViewControllerTransitioningDelegate everything is fine. These two methods are called. Why? What is the difference?
Declaration for transitioningDelegate in UIViewController:
weak var transitioningDelegate: UIViewControllerTransitioningDelegate?
As you can see transitioningDelegate holding a weak reference. The custom TransitioningDelegate instance got released right after you created it since no one have the ownership here. When you adopt the delegate in the "controller" and assign it to transitioningDelegate 'someone' is keeping this delegate instance for you.
Is there a way to detect when a UITextView has finished scrolling? As a note, I allow the user to enable or disable paging.
Thanks.
UITextView is a subclass of UIScrollView, which has a UIScrollViewDelegate class for controlling behaviour related to scrolling. One of its methods is scrollViewDidEndDecelerating. You can make your view controller implement this protocol, set your UITextView's delegate property to the view controller, and then implement the scrollViewDidEndDecelerating method. When the method is called, the UITextView will have finished scrolling. e.g.:
in .h:
#interface MyViewController : UIViewController <UIScrollViewDelegate>
in .m:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"Finished scrolling");
}
In Swift:
class MyViewController: UIViewController, UITextViewDelegate {
weak var textView: UITextView!
override func viewDidLoad() {
self.textView.delegate = self
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
...
}
}
UITextViewDelegate inherits UIScrollViewDelegate