Unable to simultaneously satisfy constraints - UIScrollViewAutomaticContentSizeConstraint - objective-c

I recently added constraints to my prototype cell on a uitableview view and have run in to this warning when running my application (no errors but see this exception in the console log). I am adding objects to a mutable array dynamically based on specific conditions and inserting to the top of my uitableview. The insert rows also have variable heights.
The issue doesn't occur when I initialize an array with predetermined value, only when I add objects dynamically and push new view controllers.
I understand uitableview contains a scroll view and I have constrained the uitableview, but for some reason the error below says I have a scroll view constraint issue. I am not quite sure what it means.
All of my constraints were created using storyboard on Xcode 5. Dynamically changing height or the cell is done programmatically.
<_UIScrollViewAutomaticContentSizeConstraint:0x17597a10 UITableView:0x18416000.contentHeight{id: 79} == -110.000000>"
)
Will attempt to recover by breaking constraint
<_UIScrollViewAutomaticContentSizeConstraint:0x17597a10 UITableView:0x18416000.contentHeight{id: 79} == -110.000000>

I had a similar error. I my case I solved it by returning UITableViewAutomaticDimension for the estimated row height, instead of a fixed number:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
I found the solution here: Autolayout Error with UITableView

Same error with same circumstances, when i changed an entry of the MutableArray (_detailColumns). The error only appeared once, not at following changes!
I had included the Update in
[self.tableView beginUpdates];
[[_detailColumns objectAtIndex:tag]setValue:textViewText forKey:#"content"];
[self.tableView endUpdates];
After removing beginUpdates and endUpdates, the message was gone (?!)

Related

OSX NSTableView insertRowAtIndexes

i already checked Using NSTableView insertRowsAtIndexes solution but It does not solve my problem.
i want insert row in nstableview at particular index(add dynamically)
index Set is valid, still it causes Program crash
NSIndexSet *indexSet=[NSIndexSet indexSetWithIndex:i];
[myTableView insertRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectFade];
1)is any thing wrong in my code?
2)Is there any another way to add row at particular index(add dynamically)?
The code is correct but first you have to insert the model object in the data source array to keep model and view in sync.
I got My mistake..... problem In other Code so This code is fine
But I want to add some points About insertRowsAtIndexes: method
Hope it will helps to other people
1)Dont called reloadData() because you are adding particular number of rows so calling reloadData() will reload all data and it will causes crash
2) Calling this method multiple times within the same beginUpdates and endUpdates block is allowed, and changes are processed incrementally
3)Most Important thing is indexSet must be within range
if you are Enter valid indexSet then The numberOfRows in the table view is automatically increased by the count of indexes.
4)you can select animation according to your need
Sample Code :
[yourTableView beginUpdates];
NSIndexSet* theIndexSet = [NSIndexSet indexSetWithIndex:[self.yourTableContents count]-1];
[yourTableView insertRowsAtIndexes:theIndexSet withAnimation:NSTableViewAnimationEffectFade];
[yourTableView endUpdates];

Deleting A TableView Cell Populated By A Dictionary

So, deleting a table view cell is pretty straight forward. You remove the object from the array, and reload the table views data. Now... I have a table view that is populated from an NSMutableDictionary rather than array (we need to because we are parsing data and storing it). Does anyone know how to delete a cell via this method? I've tried simply calling [tableView reloadData]; which surprisingly worked, but obviously created an endless loop. I do not like endless loops. Does anyone have any suggestions? I couldn't find any relevant information in my research.
This is some relevant code in the cellForRowAtIndexPath delegate:
if (![frString isEqual:#"COOL STUFF"] && [subString isEqualToString:#"COOL"]) {
NSLog(#"A COOL is showing where it shouldn't, and it's %#", subString);
//remove all cells starting with COOL
[myDictionary removeObjectForKey:[self.dictName objectAtIndex:row]];
[tableView reloadData];
}
Also, I'd rather hide the cell instead of permanently removing the info from the dictionary. Is this possible?
There are a few things you're doing wrong :
You shouldn't remove the rows in the cellForRowAtIndexPath, because that's called when the tableview wants to render. So you remove a row, and then it renders again, calls cellForRowAtIndexPath:,...
Either delete the rows, or reload the data. deleteRowsAtIndexPaths: deletes sets of rows with animation, reloadData reloads the whole tableView, so it cancels the animation, and deleteRowsAtIndexPaths: becomes pointlesss
Ensure that you return the proper numberOfRowsInSection: did you remove the data from your dictionary ?

Dynamically updating sections of UITableView without using reloadData

First off I sincerely apologize if this has been answered. I have been battling with this for too long. I would appreciate any kind of help.
I am developing an application that gets data asynchronously from different web sources and parses it into objects that are handled by my main Model. This model provides information for a UITableView. When data is received and parsed, i need to modify the number of sections and rows in the table view. I first receive the data that decides the number of sections, and then asynchronously data that modifies the number of rows in each section and their content. I have the table views data sources set up.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [self.sijainti.pysakit count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
//if ([[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count] == 0) return 1;
NSLog(#"ajatStr of section: %d count: %d",section, [[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count]);
return [[[self.sijainti.pysakit objectAtIndex:section] ajatStr] count];
}
The object names are in Finnish (long story). The second line of numberOfRowsInSection was commented to ease debugging. Now, because the data is dynamic i need to update the interface when i have data ready for display, or the user wont know about it until they scroll away and back again. I have a method for this:
- (void)updateRowWithCell:(SCPysakki *)valmisPysakki {
if (!valmisPysakki.isInArray) return;
int section = [self.sijainti.pysakit indexOfObject:valmisPysakki];
[self.tableView beginUpdates];
NSIndexSet *sectionSet = [NSIndexSet indexSetWithIndex:section];
[self.tableView reloadSections:sectionSet withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
This is called only after the number of sections is known. I do NOT want to use reloadData due to efficiency, and animation. I used to have this set up so that i had only rows and was just drawing rows inside of the rows. But once the rows became taller than the iphone screen, it became very unclear, because you couldn't see the title. So i made them sections, and the rows drawn real rows. Then i was suddenly faced with a problem. reloadRowsAtIndexPaths: withRowAnimation: worked absolutely fine but using reloadSections: withRowAnimation: gave me this exception:
* Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037
2012-09-17 04:11:27.769 pysappi[2351:f803] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
I was able to eliminate this by adding the [self.tableView endUpdate] and [self.tableView endUpdate] to the update method. But oh no, that only works if I:
Use reloadData after receiving the data deciding the number of sections (which in turn shortens the tableview so that after the whole update the user at the top of the table after every single update. I would rather update the sections dynamically, without using reloadData, except when removing Sections, but if I try to do this i get the exception again.)
update the sections after receiving data for only one Row (so if I try to update all the rows in the section once I've received all their data, I get the exception again.)
Now this creates a situation where creating a good user interface becomes impossible. I'm convinced that the underlying problem is not solved with the start and end updating calls, but that just fixes it for some very very odd reason.
I also tried adding the rows manually with insertRowsAtIndexPaths: and updating them manually also, but this returns the exact same error. During a long debugging progress i have been able to determine that this exception rises after cellForRowAtIndexPath: gets called and it returns a cell for one of the new rows that was added during the updating, even though the numberOfRowsInSection should have updated the amount of rows. I also suppose that if those few circumstances apply this is why the start and end updating methods make the row updating work.
The only thing that has worked outside of what i explained above, is using only reloadData, but that is just practically impossible considering the amount of updating.
This became a lot longer than i thought, and its 4.30 AM. Not the first time I'm up this late thanks to this exception. If you need more information ask. Thank you in advance.
(Answered in the comments. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
#deleted_user wrote:
number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), - you had a section with zero rows and did an update with a row - cocoa didnt see that as an insert and failed you

Target Action data source update for view based NSTableView

I have situation where I use view based Table Views and don't want to use bindings between data source and table view. This is mainly due to the fact that my NSTableCellView can have multiple subviews, complex validation and triggered calls to methods in other objects.
We have very clear path of updating NSTableView with data source with:
tableView:viewForTableColumn:row:
However, for backwards, that is updating datasource with updates in NSTableView we have nothing of the sort we have for cell based Table views:
tableView:setObjectValue:forTableColumn:row:
Target Action pattern is suggested instead. So, I have basically 2 questions:
If I set target and action for one specific view, or its subview, how do I get proper row and column info to know what to update in data source?
Should clickedRow and clickedColumn from NSTableView do the trick, although I have edited or changed one subview object?
How can I inform the target (as other object, not NSTableView instance) about row and column if action will pass for example NSTextField as parameter?
I can basically come to clickedColumn and clickedRow (if those 2 properties are proper answer to first question) through subview tree, but I find this as pretty much non-elegant solution and have hunch there is a better way....
THanks in advance....
NSTableCellView has an objectValue. Presumably you're already setting it, so the action can use [(NSTableCellView *)[sender superview] objectValue] to find out which object it needs to manipulate.
I suggest that you also subclass NSTableCellView and implement the action there. If you need access to other parts of the model, you can add an outlet for your view controller.
If you really need the row number, you can call indexOfObject on your content array.
The two NSTableView Methods rowForView and columnForView should do the trick.
You can call them with the sender of an Target/Action Method, like one triggered by an NSButton in your TableView (its ok, to have it somewhere in a subwiew)
Or you can call these Methods from within a delegate method implementation like the textDidChange from NSTextDelegate. So you can easily update your corresponding Array.
If you don't want continous updates textDidEndEditing would also do the job.
- (void)textDidChange:(NSNotification *)notification
{
NSTextView *tv = [notification object];
int r = [tableView rowForView:tv];
int c = [tableView columnForView:tv];
NSLog(#"Row: %d Column: %d", r, c);
// updating code here
}

NSInternalInconsistencyException when trying to dynamically modify number of rows in UITableView

I am attempting to use insertRowsAtIndexPaths so I can insert a table row. I am getting this error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted).'
What I am trying to do is to dynamically modify the number of rows in section in my attempt at rectifying the problem:
NSArray *indexPathIndex = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:0], nil];
[myTableView beginUpdates];
//***** HERE I AM TRYING TO DYNAMICALLY INCREASE NUMBER OF ROWS
[myTableView numberOfRowsInSection:1];
////////////////////////////////////////////////////////////
[myTableView insertRowsAtIndexPaths:indexPathIndex withRowAnimation:UITableViewRowAnimationTop];
[myTableView endUpdates];
Initially, my number of rows in section is 0. I try to increase this number in my efforts to address the aforementioned error however the code [myTableView numberOfRowsInSection:1] seems to have no effect.
Could somebody please suggest how I can fix this problem?
Thank you,
Victor.
You should not be setting the number of rows yourself, the UITableView manages that on its own. Remove the line.
myTableView numberOfRowsInSection:1];
Take a look at the UITableViewDataSource protocol, particularly the tableView:numberOfRowsInSection method. This will allow you to dynamically set the number of rows in the section.
A tableView has a datasource that is generally an array, that you can use to fill the cells of the tableView.
- (UITableViewCell*)tableView cellForRowAtIndexPath..... {
//Dequeueing or alloc-init-ing a cell
SomeClass *someObject = [someArray objectAtIndex:indexPath.row]; // Something
// like this, where someArray becomes the source array.
...
}
Now in some other part of your code, if you want to dynamically change the contents of the tableView, change the someArray and then change the tableView.
[someArray insertObjectAtIndex:someIndex];
[myTableView insertRowsAtIndexPaths....]; //The indexPath is generally
// consistent with the someIndex.