High Sierra update causes NSTableView to flip and scramble - xcode9

I'm updating an existing project which has worked fine for years to High Sierra. The view loads correctly and looks as it always has:
Then, after I open a popup and close it again, the view moves things around, flips things, and generally looks very crazy:
Notice the Info title drops to the bottom, the left side text items reverse order, and the date and dropdown text flip. Mouse interaction seems very scrambled as well when this happens.
I'm not sure where to even start with solving this one, anyone have any ideas?
This is using xcode 9 beta 5 and High Sierra Beta 6.
Update: This is also in xcode 9 GM and High Sierra GM Seed
Update
I have determined this happens when I call reloadData on the NSTableView that this view is within. So the question now seems to be how to refresh the table data without it going wonky.

It seems that reloadData and also reloadDataForRowIndexes:columnIndexes: both produce odd behavior in High Sierra. My way around this is as follows:
-(void)refreshAllCells {
NSMutableIndexSet* rowIndexes = [[NSMutableIndexSet alloc] init];
if (self.myTable.numberOfRows != 0)
[rowIndexes addIndexesInRange:NSMakeRange(0, (self.myTable.numberOfRows))];
[self.myTable removeRowsAtIndexes:rowIndexes withAnimation:NO];
[self.myTable insertRowsAtIndexes:rowIndexes withAnimation:NO];
}
If there is a better answer I would still love to see it.

For me, adding wantsUpdateLayer in my subclass fixed the problem.
override open var wantsUpdateLayer: Bool {
return true
}

In IB, tick the checkbox to use CALayers on your tableView's views. I toggled them on for all the view's in the tableView view hierarchy and all the flipping stopped!
Can't post an image as I don't have enough reputation but this link shows the IB checkbox:

I've encountered this bug as well and while implementing another answer I found the real reason for the bug due to an exception that now got raised:
In my case, reloadData was called again while reloadData was still being executed. This caused the rendering issues.
The "loop" was happening as a side-effect of calling tableView.makeView(withIdentifier: identifier, owner: self) in tableView(_:, viewFor:, row:). The owner: self caused awakeFromNib() of the controller getting called again which in turn triggered the reloadData(). In my setup, I was not (yet) using separate XIBs for the table cells but was using the cells that were setup inside the table view as visible Interface Builder.
So the solution was to change tableView.makeView(withIdentifier: identifier, owner: self) to tableView.makeView(withIdentifier: identifier, owner: nil) and also use separate XIBs for the table cells.

I'm seeing this as well in 10.13, when 10.12 had worked just fine. I was able to work around this problem by, oddly enough, re-adding the cell view's subviews in its [layout]:
- (void)layout{
if([self needsLayout]){
for(NSView* v in [[self subviews] copy]){
[self addSubview:v];
}
}
[super layout];
}

I experienced this as well. Further testing revealed that the contents were being drawn WHILE the tableview Data source was being updated. By eliminating a spurious update, I was able to eliminate the issue.
I reload the data in the draw method, however I have moved the data update code outside of that method. Not sure if this helps the OP, but it worked for me.

All of a sudden I received several mails from customers who complained about all table texts being shown vertically flipped. All of them use macOS Mojave.
After a lot of hacking, and trying the solutions detailed above (to no avail alas), I decided to disable the autoSave property of the NSTableView:
//Swift.print("Now setting autosaveName of primaryView to \(self.className).primary")
//primaryTableView.autosaveName = "\(self.className).primary"
//primaryTableView.autosaveTableColumns = true
Then the problem was instantly gone. But now my customers weren't able anymore to change and save the column widths and order. So, instead of doing it programatically with tableView.autosaveName = "autosavename"; I now set up the autoSave property in the Table view properties, and also checked 'Column information' in the Attributes Inspector (while showing xib file). And then it works just fine..
I use the currently latest version of Xcode (10.1 10B61), and the problems only surfaced when using macOS Mojava 10.14.0 - 10.14.2 . High Sierra and Sierra gave no trouble. Whether I compiled the project in High Sierra or Mojave made no difference.
So, I hope this helps for other people confronted with this bizarre problem. I think it's a bug in macOS Mojave.

Had the same problem, reproducible on High Sierra and Mojave. The issue was with NSOutlineView autosaveName, other solutions didn't help. However I needed this feature.
Moving adding/reloading data to "viewDidAppear()" instead of "viewDidLoad()" solved the problem.
Edited:
It happens only when:
autosave is present
items get loaded on viewDidLoad before sorting is applied
the same list of items gets re-loaded after sorting is applied
all of the above happens on viewDidLoad
If you try to access tableView.sortingDescriptors (or NSOutlineView) - it automatically applies sorting. If it happens before loading the data - it works ok.
Loading data on viewDidAppear still looks like a better option.

Related

Xcode Interface Builder 9.1 Collection View Cells have too small "expected height"

Recently, I encountered a problem with the Interface Builder which I failed to solve. I'm using a UICollectionViewController and whenever I add a Cell it immediately shows a orange rectangle (indicating a auto-layout update). Updating the frame/cell doesn't change anything. The warning associated with the orange marking reads "Expected: height=Y, Actual: height=X" where Y is always exactly X-100. That is: When I set a custom cell height of 193, it says "Expected: height=93". This happens no matter which size I enter.
The problem with this is that I have many difficulties with the subviews and their constraints. For instance, if I add a subview with the constraint to keep the same height as the cell, it will be shown as 93 (the expected height), even though my cell should be 193. Layouting becomes impossible.
I tried adding a new cell, same issue. I tried removing every subview and re-adding them, nothing.
Any ideas are highly welcome.
Thank you very much!
Solution found ! (Xcode 9.2)
The bug seems to only happen when you try to embed the UICollectionViewController in a Container View in the storyboard. The workaround is to remove the segue while you set your constraints, and re-add the segue once your constraints are well set.
I also think that setting UICollectionViewController size as Freeform could be responsible of the bug. If so, try to set constraints before changing the size.
Hope this helps !
I'm not sure if this solved it, but the warning and issue disappeared once I did the following:
Select the CollectionViewController in Interface Builder and set the size to freeform and make the height larger, large enough to show all your template cells. (Plus: maybe refresh the views). That solved the issue for me.
In my case, I have added two collection view cell, withing collection view Controller.Only setting the view controller to free form wont help us. Need to update the size, to get rid of the warning.
updating collection view cell frames, wont help us. Warning will be continuously changing its length.
I tried to work without considering the warning, as I have set my collection view cell size programmatically and it does working as expected.
I think it's just a strange bug
I delete the collectionViewController in SB, then create a new one, the problem disappear
This is a common bug with Interface Builder. I don't know the exact cause, but I believe it's something to do with placing collection views inside arrangement views that do not have an exact size. I've seen it when putting them in scroll views, stack views and container views.
There is a simple fix, although I believe this to be a bug in IB that ought to be corrected by Apple rather than hacking around it. The solution (for me at least - your mileage may vary!) is to place the collection view inside an ordinary UIView and pin its edges to it, then place that parent view in the position that you wanted your collection view with all the constraints it required.
I usually found that there were actually no auto layout issues at run-time, which is why I believe this to be purely an Interface Builder bug.

UITableviewcell width not filling the screen

I don't know if this is a bug with AutoLayout or Xcode but I've realised that if I run my application on a device which isn't the same size as the device in my storyboard, the elements are adopting the incorrect size.
I.e. Selecting View as iPhone SE and running the application on an iPhone 7+ The size of my tableview is the width of an iPhone SE screen, this fixes itself when I reload the view and then it then adopts the width of the iPhone 7+ screen.
Just a note as well the table view doesn't have a fixed width and is pinned to the top, bottom, left and right with 0 spacing and also I'm changing the height of the cells programmatically in code if this could affect it at all as well.
Video: https://drive.google.com/open?id=0B0QLbDLfJn6_YzljUGg4RTUwaTg
Views that come from a xib (or storyboard) have their IB frame values when they are created, before they are added to the view hierarchy. So a case like you describe is probably that something is accessing a view loaded from a xib before it has become part of the layout process and resized.
This would also explain why it's fixed when you go away and come back. The first time, it got the values before they were final, but the second time the values are already final and correct.
Layout code called fromviewDidLoad() for view controllers, or awakeFromNib() or initWith(coder:) for views is the likely cause. Layout code called from viewDidLoad() is especially problematic because it was fine up to iPhone 5s, but would now cause this problem.
It's impossible to say what exactly the issue just from this. From the NSLog statements visible in the video, the issue is whatever code calls that "weather view width". That is being called too early in the layout process. It needs to go in viewWillAppear or viewWillLayoutSubviews to make sure the correct values are ready for whatever calculation is dependent on that. Hope this helps.
I can't seem to recreate this. I would recommend double checking for any updates for Xcode and the Developer tools (softwareupdate --install -a).
Incase you haven't, restart Xcode.
EDIT: Disregard this answer, please read Mike Sand's post.
Try self.view.layoutIfNeeded in viewDidLoad or in viewWillAppear

A popup, "Failed to automatically update constraints" pops up in Xcode 6.3.1

When I added a couple of controls in my viewcontroller in storyboard and click
Resolve Auto Layout Issues -> Reset to Suggested Constraints.
The following popup appears and I cannot perform auto layout constraints.
Though, when I remove the Prototype Cell (which has a couple of labels and an imageview) from my tableview then auto layout works fine. Any thoughts?
Edited:
And manually adding constraints to individual elements work fine as well. After manually setting the image view inside prototype cell, the auto layout has started working fine without popping up that popup. So, maybe, sometime, it is hard for auto layout to figure out all these constraints itself.
Try clearing constraints before resetting them, this has worked for me before.
I had the same problem when using prototype cells in a UITableView and some other views in a UIViewController.
My solution was to select all the elements in the prototype cell and see if these had red or orange markers (constraint conflicts/problems). These elements I cleared the constraints for and afterwards I had no problem telling the entire view to "Reset to Suggested Constraints".
Obviously, Interface Builder has a problem resetting embedded table content constraints.
Actually . If you import different storyboard from another Xcode project. This is not possible to avoid problem. My personal advice is create a new UIViewcontroller or stroyboard. And step by step add items. But. I did not do this.
I lived three times. In fact When I saw this message. I was configuring tableview or UITableviewcell. At the end of the story I have fixed my problem. But There is no gold key for issue. I will explain as much as possible.
for All Views in View Controller select Clear Constraints
If you are using tableview or collection view. please delete.
I assume. there are label, button and scrollview on the project. Please add missing constraints. If you leave problem again. You need to delete any of them.
for All Views in View Controller Reset to Suggested constraints.
If you don't leave problem again. PERFECT. If there is a reverse situation
for All Views in Second View Controller select Clear Constraints
delete any of item. Select add missing constraints again.
Continue to try the third and fourth steps. Until you find the faulty objects.
I'll try to help you if you submit your project.
Good luck .
Following Solution work for me.
Actually initially i used Free-from storyboard of size 600 into 900 that time i was getting this error. so i deleted that storyboard and again drag and drop element and make connections, then i solved issue.
I have faced same problem with Xcode 6. In my MainViewController I have a tableview with custom TableviewCell. In Interface builder itself I have taken taken 2 labels on tableview cell.
When I try to add constraints it gives me error. I did remove prototype cell in tableview and worked with nib with customCell. Be careful while working with custom tableViewCell.
Let me know if you need any additional information.
I had same issue last evening, After many try and error i found that it was just a corrupt ViewController. I created a new ViewController2 with the same aspects, then applied constraints to the ViewController2, and it worked! Still not sure why exactly the other one had issues.
I had some problem with Xcode 7. I solved it very simple. I cleared constraints -
Reset to Suggested Constrains
, then applied -
Add Missing Constrains.
This has worked for me.

Another Cocoa: Crash in _NSDisplayOperationStack; Need Guidance too

Much like the question asked here, I too have problems with the NSDisplayOperationStack.
Let me make the context clear first though.
I have a window which contains a view, in there a tabView with several buttons, textviews and labels. The view inside of the tabview originates from a different NIB, which uses Auto Layout (as all of the views, buttons etc. do) and has constraints set up.
The constraints are made in IB excluding a single constraint being made in the WindowController. This constraint attaches the view of the tabView to it's superview with a visual constraint in the form of #"H:|[viewInsideTheTabView]| and #"V:|[viewInsideTheTabView]|. Next to that constraint, no constraints are being made or added programmatically.
With this context, I run and test my app only to see the following error appear after resizing the window several times.
The error:
*** Assertion failure in -[_NSDisplayOperationStack exitDisplayOperationForWindow:], /SourceCache/AppKit/AppKit-1138.51/AppKit.subproj/NSDisplayOperationStack.m:343
Exception _NSDisplayOperationStack underflow raised during heart beat. Ignoring....
When this exception is raised, the app freezes and does not become responsive again. I already checked every single button, view etc. for concurrent drawing, but none are (at least that is what IB tells me).
Is there anyone who encountered the same error and knows how to respond to it?
Thanks in advance.
Take a look at my answer within the tread you're referring to, it might be of use... My problems also only occurred in OSX 10.7, not OSX 10.8.
I tried using the same app (and resizing several times) on OSX 10.8 and it never crashes. It seems to me that Apple fixed a lot of (including this one) constraint problems on 10.8.
This makes it looks, to me at least, that 10.7 is like a test-case for their constraints. And to add some grounds for that comment; most of the methods used for animating constraints are available on 10.8 and later.
Still; if someone can counter this answer, please do!

View based NSTableView viewForTableColumn:row not called

I've got a View-based NSTableView which is configured in IB to be View based. Its column identifier is set, too. As are its dataSource and delegate set, to the same object, which claims to conform to both in the public header. I've verified these are set after the tableView awakes from its nib.
As per the docs, I've implemented -numberOfSectionsInTableView: and it gets called and returns a non-zero number.
However, -tableView:viewForTableColumn:row:, much to my chagrin, does not, and I can't figure out why not.
Does anyone know why this might happen? I'm running on Mountain Lion and my deployment target is also set to be Mountain Lion.
It' simple! The problem was, even though the tableview was added to my view hierarchy, it was clipped so it couldn't be seen. NSTableView must do some checks to see if it's actually on screen and then only request cell views for visible rows.
Because the whole tableview was essentially "off-screen", it wouldn't request any rows.
My NSTableView is added by code instead of IB, I solved it by adding:
[tableView addTableColumn:[[NSTableColumn alloc]initWithIdentifier:#"columnIdentifier"]]

Resources