MVC how is the correct way to get the values of a control in a custom cell? - iphone

I have defined a custom cell with an UISwitch control, is the GetCell method the correct place and correct way to get the values of the cell's control and assign it to a more persistent object than an object from the view? (GetCell method example).
if (indexPath.Section == 0)
{
switch (indexPath.Row)
{
case 0:
TVCellTwoColWBool cell = tableView.DequeueReusableCell(_cIDTwoColWBool) as TVCellTwoColWBool;
if(cell==null)
cell = new TVCellTwoColWBool("Date Filtering", MappedList.DateFilter, _cIDTwoColWBool);
cell.DataView.SWData.ValueChanged += (sender, e) => {MappedList.DateFilter = cell.DataView.SWData.On;};
return cell;

When you create or re-initialize the cell it is a good time to bind the state of any controls in the cell with the actual column/row that you want to attach the behavior to.
Your approach is correct, because it would update the values that you want. But sadly, because you are using ValueChanged as an event, you will be adding a new event handler every time the cell is dequeued.
So you would need to first remove the old event handler, and then add a new event handler. This means that you need to use a helper method for it to allow ValueChanged += FOO and ValueChanged -= FOO

I think this is not GetCell method,this is cellForRowAtIndexPath.
And yes its a correct place to get and paste the values in the cell.

Related

Updating cell value from callback in ag grid

I need to update the value of one of the cells in a row in ag-grid as soon as the onCellEditingStopped callback is called (this happens when a user exits any other cell on that row).
I have this code which is based on the single cell update example at Ag grid single cell update
onCellEditingStopped: {function(event) {
event.node.setDataValue("cell_to_update","a new value");
}
}
which should update the cell with field "cell_to_update" but it doesnt.
I am wondering if that is because I am calling it from this specific callback?
One way is by forcing the refresh, like
onCellEditingStopped: {function(event) {
event.node.setDataValue("cell_to_update","a new value");
event.api.refreshCells({force:true});
}
}

How could I add custom row focus class in ag-grid

I want to control row focus process. I need to show confirm dialog on row focus change in my table.
I tried to do this with rowClassRules property, but as I understood that functionality apply classes when table rendering, after that row classes stop changing
rowClassRules = {
'custom-row-focus': (params) => {
return params.data.id === this.currentSelectedItem.id
}
}
currentSelectedItem set's when I click on the row
Found an answer in docs
https://www.ag-grid.com/javascript-grid-row-styles/#refresh-of-styles
If you refresh a row, or a cell is updated due to editing, the rowStyle, rowClass and rowClassRules are all applied again.
So, when I'm clicking to the row I should make something like that:
onClicked($event: RowClickedEvent) {
$event.node.setData({...$event.data});
}

Swift best practice: How to keep track of different objects?

I'm wondering what is a good solution to keep track of different objects of same type.
I have this function:
private extension MenuButtonsViewController {
// TODO: Find a way to find correct button based on MenuItem
func buttonFor(for menuItem: MenuItem) -> EmojiButton? {
guard let subViews = stackView.subviews as? [EmojiButton] else {
return nil
}
let button = buttonFactory.makeEmojiButton(title: menuItem.icon)
for subView in subViews where subView == button {
return subView
}
return nil
}
}
I have an array (UIStackView) with a varying number of buttons (EmojiButton). The buttons are created with content from MenuItem.
I'm looking for a good and clean solution how to find and remove a particular button from the stackView array, based on a MenuItem.
So far I had three ideas:
To create a new object, initalized with same values as the one to remove, and then match using ==. (Solution above). This didn't work.
To add an id to all buttons, and then a corresponding id to the MenuItem object. But this doesn't seem like an elegant solution to have to add that everywhere, and expose this variable from the button object.
Maybe store the button in a wrapper class (like MenuItemButton) with an id to match to, or by storing the MenuItem object so I can match against that.
Any ideas? How is this usually done?
If MenuItem and EmojiButton inherit from UIView, you can make use of the tag property that is available on all UIView's.
You first need to assign a unique tag value to each of your MenuItem's.
You then need to assign this same value to the corresponding Emoji button's tag property. (This would be a good thing to do in your factory.)
Having done that, you can modify your function as follows:
//assumes MenuItem and EmojiButton inherit from UIView
func buttonFor(for menuItem: MenuItem) -> EmojiButton? {
return stackView.viewWithTag(menuItem.tag) as? EmojiButton
}

Swipe Cell in UICollectionView - Swift

Is there an elegant and short way to progrematiclly swipe between two cells (assuming we have the desired NSIndexPath of the two cells)?
I see few possibilities here, having the information you provide.
1) You can use standard UICollectionView method: - moveItemAtIndexPath:toIndexPath:, but you must update your data source first. For example, assume you already updated data source (note that this example code is useless until you figure out index changes after moving items.):
collectionView.performBatchUpdates({ () -> Void in
collectionView.moveItemAtIndexPath(firstIndexPath,toIndexPath:secondIndexPath)
//note: proper indexes might be changed after moveItem.. method. Play with it and you'll find the proper one for your item.
collectionView.moveItemAtIndexPath(secondIndexPath,toIndexPath:firstIndexPath)
}, completion: { (finish) -> Void in
})
2) You can recalculate your layout if you use custom layout
3) You can just reload collection view with reloadData or reloadItemsAtIndexPaths E.g.:
var dataSourceArray = [1,2,3,4,5]
// some event occurred -> dataSourceArray changed
dataSourceArray = [1,2,5,4,3]
// call collectionView.reloadData() or reloadItemsAtIndexPaths(_:).
If you'll use 1st or 3rd way, in both cases data source must be up to date.

Custom iPad keyboard that looks like the system keyboards

I'm looking for a non-hackish solution for this, so basically -inputView. The part that I'm not sure about is how to make it look like the regular keyboards, from the background to the keys. I realize that I could photoshop an apple keyboard, but this seems like it is a little hackish, especially if apple (probably not but still possible) decides to change the look of their keyboards. I know Numbers has done an excellent job of making extra keyboards that look like the standard system ones, and I would like to do it like those (although obviously they have access to the same resources that made the system keyboards, including possible private frameworks, etc.)
I used the following:
tenDigitKeyboard.m
-(IBAction)pressedKey:(UIButton *)sender
{
[delegate pressedKey:sender.tag];
}
where delegate is defined as `id delegate;
then in the delegate i do...
-(void)pressedKey:(NSInteger)key
{
NSString * bufferString = model.string;
if (key == -1) {//delete
model.string = [bufferString substringWithRange:NSMakeRange(0, [bufferString length]-1)];
}else{
//will need to change the following to lookup key value based on a lookup of the button.tag
model.string = [bufferString stringByAppendingFormat:#"%i",key];
}
[self update];//updates the view
}
I got the keyboard button artwork from: http://www.teehanlax.com/blog/iphone-gui-psd-v4/
Create a view controller and xib. The xib should have 1-9,0 and delete buttons mapped to IBOutlets in your controller. Store and retain the return value string as a property. You can add decimals, etc. if you wish. In the header, store an edition block closure with a property (or alternatively create a delegate or use notification).
#property (copy) void(^valueChangedBlock)(NSString* string);
On touch up, each button sends an event to a method like this:
- (IBAction) pressKey:(id)sender
{
NSString *toAppend;
// Instead of this switch you can store the values in a dictionary mapped by sender.
switch(sender)
{
case oneButton: toAppend=#"1"; break;
case twoButton: toAppend=#"2"; break;
...
}
returnValue = [returnValue appendString:toAppend];
valueChanged(returnValue);
}
Obviously the delete key should remove a character from the end of the string instead of appending. Other than creating the controller and adding this view as the inputView, you should add the valueChangedBlock and set it to update the text field. You may want to put a clear custom button over the text field set to make the field first responder so it doesn't appear as if the user can edit at any point in the string.