Headers disappear when after overriding TableView.Scrolled - iphone

I have been in a pickle with this problem for a while now. When I try to manually handle how my table behaves while scrolling, everything works fine, except all my section headers disappear. What I tried to do was make the scroll view expand after I have scrolled for X number of points. The headers are not visible from the very start, but when I comment the override out, my headers are there as normal. Does anyone have any idea how I could fix this and make my section headers appear ?
A sample of my code is as follows :
dialog.TableView.Scrolled += delegate {
if (dialog.TableView.ContentOffset.Y > this.View.Frame.Height)
{
dialogView.Frame = new RectangleF(0,0,320,this.View.Frame.Height);
}
};

If you subscribe to Scrolled on a UITableView, it will likely overwrite the underlying UITableViewSource that tells it how many sections/rows there are, etc.
It looks like you are using MonoTouch.Dialog, is the table simple enough where you could use a normal UITableView for this case? There is a Scrolled method you can override on UITableViewSourceinstead of using the C# event.

Related

Constraint constant changes but layout doesn't get updated?

I have a strange problem: in my table view I want to update a single cell when its UISlider gets modified (value changed control event). At the moment the value of the slider changes, I want to animate a button into the cell (sliding in from the right). I set the constant of the button's constraint to -50 to make sure it's not visible by default, and when the slider's value gets changed, a method gets called which updates the table view, so cellForRowAtIndexPath gets called again for all cells in my table. Simplified it looks something like this:
func valueChanged(sender:UISlider) {
// Reload table view
self.myTableView.reloadData()
// Let table view know the value of the slider got modified
self.didChangeValueOfSlider = true
}
And in cellForRowAtIndexPath I'm keeping track of which cell's slider got changed by using a custom selectedCellIndexPath variable. When the table view gets to the cell that got modified: it runs the following code:
// Check if cell is selected
if indexPath == self.selectedCellIndexPath {
// Check if value of slider was changed
if self.didChangeValueOfSlider == true {
// Value was changed: set constraint back to default
saveButtonTrailingConstraint.constant = CGFloat(15)
self.view.setNeedsUpdateConstraints()
self.view.updateConstraintsIfNeeded()
// Reset slider update status
self.didChangeValueOfSlider = false
}
}
Calling those setNeedsUpdateConstraints() and updateConstraintsIfNeeded() might be overkill or unnecessary, but please note this is my 15th attempt or so to actually get the view to display the updated layout. I used breakpoints to confirm the constant actually changes, after the code above is finished running and everything works perfectly fine. The only thing I can't get working is the updating part. I've tried UIView.animateWithDuration to animate the change, and I've tried methods like layoutIfNeeded() and beginUpdates() and endUpdates of the table view: nothing works. What could be the reason the layout doesn't get updated? And what am I supposed to be calling the layout and update methods on? I've been calling them on self.view but I'm not even sure if you're supposed to be calling it on the view if you're trying to update the layout of a table view cell. Any help would be appreciated.
I figured it out. The problem turned out to be the constraint itself. as I was accessing the wrong one. I defined it as saveButtonTrailingConstraint but I was actually modifying was the saveButton's width constraint (which apparently can't be animated). Instead of accessing saveButton.constraints[indexOfTrailingConstraint] I should have defined saveButton.superview!.constraints[indexOfTrailingConstraint] as the constraint belongs to the superview and not to the button itself. I guess the best thing to take away from this clumsy mistake is to always double-check if you're modifying the correct constraint if you're doing it programmatically, because it doesn't always show on the first eye.

VerticalLayout dynamically hiding visibility

I was wondering whats the best way around dynamically hiding some menu items. At the moment I have 6 items just in a matrix layout row. I want to have 3 items aligned left and 3 items alligned right. If one of the items is set to not visible I want it to move accross. I've done something similiar in a horizontal layout and setting the visibility to hidden. I was wondering if this would work with a vertical layout? Having trouble trying to figure out exactly how I would do it as I'm quite new to UI5 xml css and javscript. Any help would be great.
Also I'm having one other issue unrelated to this, I cant seem to bind my json model to my xml fragment, if I use the same code on my normal xml view it prints out the model data. But on my fragment it just prints it like {person>/fullName} any ideas ?
Belongs to your second question.
Maybe your binding was quoted on copy and paste? Check the native XML Code.
If no data are shown (not "{person>/fullName}"), add dependent to connect the models of your view
var oFragment = sap.ui.xmlfragment(sFragment, "fragmentName", this);
oView.addDependent(oFragment);

GWT 2.4 DataGrid automatic scrolling when selecting an item

I am using GWT 2.4's new DataGrid in a project. I configured the DataGrid with a pagesize of 50.
The available screen is not big enough to display all items and thus a vertical scrollbar is shown (this is actually the main purpose for using a DataGrid in the first place).
I attached a SingleSelectionModel to the DataGrid in order to be able to select items.
This works fine so far.
However I also have another widget with which the user can interact. Based on that user action a item from the DataGrid should be selected.
Sometimes the selected item is not in the visible screen region and the user has to scroll down in the DataGrid to see it.
Is there any way to automatically or manually scroll down, so that the selected item is visible?
I checked the JavaDocs of the DataGrid and found no appropriate method or function for doing that.
Don't know if this works, but you could try to get the row element for the selection and use the scrollIntoView Method.
Example Code:
dataGrid.getRowElement(INDEX_OF_SELECTED_ITEM).scrollIntoView();
The answer above works pretty well, though if the grid is wider than your window and has a horizontal scroll bar, it also scrolls all the way to the right which is pretty annoying. I was able to get it to scroll down and stay scrolled left by getting the first cell in the selected row and then having it scroll that into view.
dataGrid.getRowElement(dataGrid.getVisibleItems().indexOf(object)).getCells().getItem(0).scrollIntoView();
Don't have time to try it out, but DataGrid implements the interface HasRows, and HasRows has, among other things, a method called setVisibleRange. You just need to figure out the row number of the item that you want to focus on, and then set the visible range from that number n to n+50. That way the DataGrid will reset to put that item at the top (or near the top if it is in the last 50 elements of the list backing the DataGrid). Don't forget to redraw your DataGrid.
Have you already looked at this? If so, I'd be surprised that it didn't work.
Oh, and since this is one widget talking to another, you probably have some messaging set up and some message handlers so that when the user interacts with that second widget and "selects" the item, the message fires on the EventBus and a handler for that message fixes up the DataGrid along the lines I've described. I think you'll have to do this wiring yourself.
My solution, a little better:
dataGrid.getRow(model).scrollIntoView();
I got a Out of bounds exception doing the above.
I solved it getting the ScrollPanel in the DataGrid and used .scrollToTop() and so on on the ScrollPanel. However, to access the ScrollPanel in the DataGrid I had to use this comment:
http://code.google.com/p/google-web-toolkit/issues/detail?id=6865
As Kem pointed out, it's annoying the "scrollToRight" effect after the scrollIntoView. After me, Kem's solution gives a better behaviour than the base one as usually the first columns in a table are the more meaningful.
I improved a bit his approach, which scrolls horizontally to the first column of the row we want to be visible, by calculating the first visible column on the left before applying the scroll and then scrolling to it.
A final note: Columns absolute left is tested against "51". This is a value I found "experimentally" by looking the JS values in the browser's developer tool, I think it depends on the table's style, you may need to change/calculate it.
Below the code:
public void scrollIntoView(T next) {
int index = datagrid.getVisibleItems().indexOf(next);
NodeList<TableCellElement> cells = datagrid.getRowElement(index).getCells();
int firstVisibleIndex = -1;
for(int i=0; i<cells.getLength() && firstVisibleIndex<0;i++)
if(UIObject.isVisible(cells.getItem(i)) && (cells.getItem(i).getAbsoluteLeft() > 51) && (cells.getItem(i).getAbsoluteTop() > 0))
firstVisibleIndex = i;
cells.getItem(firstVisibleIndex>=0? firstVisibleIndex : 0).scrollIntoView();
}

Scala: Button in Table Cell does not "fire" Action

I've got a little Problem: I want to have Buttons in some of the cells of my Table. As rendering component I return a Button with the following code: (theres application specific and debugging code in this example but you'll get the picture)
class LivingTreeButton(lt:LivingTree[_], client:TableBehaviourClient) extends Button(Action("xx") {
println("fire!")
lt.expanded = !lt.expanded
client.refresh
}){
println("I print therefore I am")
}
now when I scroll to one of the Buttons in the Table I see the "I print therefore I am" printouts and I do see the buttons with the "xx" text. But when I press one of the buttons nothing happens and I don't even see the "fire!" printouts.
It doesn't work neither, when I define the Action in the Buttons body instead of the constructor.
As further background info:
I'm not blocking the tables Events or anything. I only have a to listeners set up in JTable
peer.getColumnModel().addColumnModelListener(behaviourWorker)
peer.getTableHeader().addMouseListener(behaviourWorker)
and only temporarily block one of my own events in the Tables subclass:
listenTo(this.selection)
reactions += {
case e#TableRowsSelected(_,_,true) => if(!blockSelectionEvents) publish(PimpedTableSelectionEvent(this))
}
has any of you ever struggled with the same problem or has any idea what might be going wrong. After 2 hours od resultless debugging I would be thankfull for ANY hint.
Guess I got it. Didn't know that I have to add a TableCellEditor to catch the events. Doesn't really work yet but I'm sure that's it.

UITableView: moving a row into an empty section

I have a UITableView with some empty sections. I'd like the user to be able to move a row into them using the standard edit mode controls. The only way I can do it so far is to have a dummy row in my "empty" sections and try to hide it by using tableView:heightForRowAtIndexPath: to give the dummy row a height of zero. This seems to leave it as a 1-pixel row. I can probably hide this by making a special type of cell that's just filled with [UIColor groupTableViewBackgroundColor], but is there a better way?
This is all in the grouped mode of UITableView.
UPDATE: Looks like moving rows into empty sections is possible without any tricks, but the "sensitivity" is bad enough that you DO need tricks in order to make it usable for general users (who won't be patient enough to slowly hover the row around the empty section until things click).
I found that in iOS 4.3, the dummy row needs to have a height of at least 1 pixel in order to give the desired effect of allowing a row to be moved into that section.
I also found that the dummy row is only needed in the first and last section; any sections in between don't have this problem.
And it looks like in iOS 5.0, no dummy rows or special tricks are needed at all.
While managing the edit, you can monitor if the table view is in Edit Mode. Use that flag inside of cellForRowAtIndexPath to decide weather or not to display the 'blank' row. While in 'regular' mode, the row will not display, but when the user taps 'edit' cellForRowAtIndexPath should get called again and this time decide to display the row. The details of how to do that depend on your data source and how you are gluing it to the display. If you aren't getting the call again, you can manually inject rows with insertRowsAtIndexPaths / deleteRowsAtIndexPaths and/or call reloadData to force a refresh.
I found that if you return -1.0 from the heightForRowAtIndexPath method it will remove the 1 pixel line.