UITextField: can't type text but smilies, copy/paste, and backspace is fine - ios4

I think this is strange, I have made my own class that inherits from UIAlertView. In this class I add a UITableView as subview and the cells contains a UILabel and a UITextField.
the class implements: UITableViewDelegate, UITableViewDataSource and UITextFieldDelegate,
In the cellForRowAtIndexPath each cell.uiTxtField.delegate is set to self.
The following happens both in the simulator and on the real iPhone device:
When I set the pointer/finger in the UITextField the keyboard pops up and
textFieldDidBeginEditing is triggered, that's fine and as expected.
When I leave the UITextField, textFieldDidEndEditing is triggered,
that's also fine and as expected.
But when I start to type text, the cursor stops blinking but no text
is typed to the UITextField.
I can copy and paste text by holding down the pointer/finger in a UITextField that contains text, select copy and then paste it in another UITextField (or the same).
The backspace works fine.
It also let's me type in symbols and smilies etc.
The only thing I can't type in is characters/letters and numbers
The return button doesn't trigger textFieldShouldReturn
Since textFieldDidBeginEditing and textFieldDidEndEditing is triggered I assume my delegate setup is fine, but I can't understand why I can't type text and why textFieldShouldReturn is not triggered.
This might be related.
Any help is appreciated.

have you put this in the "init" method of your custom class?
try putting a code like this in your implementation file...
#implementation CustomAlertClass <UITextFieldDelegate>
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//
self.YourTextField.delegate = self;
}
return self;
}
#end

Short answer: Make sure you don't have any code that messes with the 'editing' property on UITextField.
I had the same symptoms where I was definitely setting the delegate properly and textFieldDidBeginEditing and textFieldDidEndEditing were getting called, but textFieldShouldReturn and shouldChangeCharactersInRange were not getting called. I also could not type any characters, but I could copy paste into the text field. In my case I also happened to be putting the text fields inside cells in a UITableView. My situation was slightly different in that the delete button did not work.
Where I went wrong, was that I was not using a raw UITextField in my cells, I had my own subclass of UITextField. My subclass had a property 'isEditing', which I was modifying in the UITextFieldDelegate methods and used to figure out how to scroll the table view when the text field was selected. This was overriding the 'isEditing' method on UITextField with is used as the getter for the UITextField 'editing ' property. Once I got rid of my subclass isEditing property everything behaved as expected.

Related

DelegateCommand<object> is not beeing invoked

I am using Template10.
I am utilizing a ListView.
The ViewModel needs to know the SelectedItems.
The SelectedItems should be passed as a parameter with a converter.
EventTriggerBehavior EventName="SelectionChanged" is tested working.
The converter is tested working.
DelegateCommand> SelectionChangedCommand is NOT working.
DelegateCommand of anything is NOT working (no string, no int - no nothing).
DelegateCommand SelectionChangedCommand is tested working.
Only DelegateCommands without parameter are working when
ListView -> EventTriggerBehavior -> InvokeCommandAction
Any ideas?
I think I found the solution.
I changed the converter, so that it is returning a List<string> instead of IList<object>. It Looks like that the DelegateCommand<T> in the ViewModel did not match the <T> coming from the the converter/ListView although ListView.SelectedItems is IList<object>. Furthermore I changed the concept, now the Delete Buttons gets the list of selected items which saves some Code, Events and doubled lists.

UILabel not wrapping in UITableView until device rotate (iOS8)

I have a custom MvxTableViewCell that is associated with an MvxStandardTableViewSource. That Source is then applied to a UITableView. The custom table cell is defined without any Storyboard or NIB. It is laid out in code and uses AutoLayout.
this.searchResultsTable = new UITableView();
this.searchResultsTable.AccessibilityIdentifier = "SearchView_SearchResultsTable";
this.searchResultsTable.TranslatesAutoresizingMaskIntoConstraints = false;
this.searchResultsTable.RowHeight = UITableView.AutomaticDimension;
this.searchResultsTable.EstimatedRowHeight = 44.0f;
this.searchResultsTable.RegisterClassForCellReuse(typeof(CustomerItemCell), new NSString("CustomerItemCell"));
this.searchResultsTable.AllowsMultipleSelectionDuringEditing = true;
this.searchResultsTable.TableFooterView = new UIView();
this.searchResultsTableDataSource = new MvxStandardTableViewSource(this.searchResultsTable, new NSString("CustomerItemCell"));
this.searchResultsTable.Source = this.searchResultsTableDataSource;
The MVxStandardTableViewSource is databound to a ViewModel property of type List
var set = this.CreateBindingSet<SearchView, SearchViewModel>();
set.Bind(this.searchResultsTableDataSource).To(vm => vm.SearchResults);
set.Bind(this.searchBar).For(x => x.Text).To(vm => vm.CurrentSearchCriteria);
set.Apply();
This all works fine until an item in the data source causes some text wrapping in one of the UILabels and consequently a different height to the other cells.
The cell height is mostly correctly calculated but the UILabel within the
cell does not get redrawn until the device is rotated. I am using iOS AutoLayout to layout the various UIViews in the Cell.
Here are some examples of the large cell in my layout, see the
person "THISISAPATIENTWITHA-" (note this is test data not real people's data)
Initial display of cells
Same cells but device has been rotated
Still the same cells with device rotated back to original
How do I get the UILabel to redraw? We only need to support iOS8 and above.
I cannot see an event or method that gets called when the data binding has happened that would allow me to effectively tell the custom cell "You now have your subviews populated with bound data so redraw them"
The table has another issue too that is covered by this question, Implementing cell reuse for varying height cells in UITableView
Simple Repro on Github
https://github.com/munkii/TableCellResizeIssue
UPDATE:
I've forked your GitHub project and submitted a pull request. But here's my updates to your project.
https://github.com/SharpMobileCode/TableCellResizeIssue
First, you're using FluentLayout for your constraints. Nothing wrong with that actually, but that's some good info to tell others. :)
Second, in order for UITableView.AutomaticDimension to work on TableView Cells, there must be enough autolayout constraints defined in order for the cell to calculate the height of the cell. UITableView.AutomaticDimension depends on proper AutoLayout constraints.
Since you were using FluentLayout to abstract iOS AutoLayout constraints, this was not obvious as no warnings were present in the application output window. Though FluentLayout was technically correct, it however wasn't enough for UITableView.AutomaticDimension to automatically calculate each cell height.
So what I did was added a few more constraints. Look in CustomerItemCell.CreateView() in the pull request (or my github link). You can see that I added additional constraints for all the bottom labels so that they add a Bottom Constraint to the ContentView (Just like you did with this.bornLabel). This had to be applied to all the labels on the bottom of the cell. This gives AutoLayout enough information to properly calculate the cell height.
Third, This almost works, but if you rotate to Landscape, you'll notice that the long name cells will be bigger and have extra padding. To fix this, I created another class called AutoLayoutLabel that inherits from UILabel. I overrode the Bounds property so that it changes the PreferredMaxLayoutWidth to the proper width when rotated to Landscape, and back to Portrait. You then will need to use AutoLayoutLabel instead of UILabel. You'll need this for all labels that need to wrap. I'm not sure how to set PreferredMaxLayoutWidth to auto in code, but this is how to do it programmatically (which also works for iOS 7).
public class AutoLayoutLabel : UILabel
{
public override CGRect Bounds
{
get
{
return base.Bounds;
}
set
{
base.Bounds = value;
if(this.Lines == 0 && Bounds.Size.Width != PreferredMaxLayoutWidth)
{
PreferredMaxLayoutWidth = Bounds.Size.Width;
SetNeedsUpdateConstraints();
}
}
}
}
Well, that should do it!
I now have a solution to this part of my issue. Prompted by #SharpMobileCode reference to PreferredMaxLayoutWidth I decided to give that another go. Rather that setting it to Automatic (which seems impossible in code) I am setting it Explicitly, once AutoLayout has done its thing. Like this
/// <summary>
/// Lays out subviews.
/// </summary>
public override void LayoutSubviews()
{
base.LayoutSubviews();
this.nameLabel.PreferredMaxLayoutWidth = this.nameLabel.Frame.Size.Width;
}
I am no longer seeing the Labels not wrap (hurrah!) however I am seeing an issue with what looks like cell reuse. Once I scroll all of the cell off the top of the screen I can scroll it back on and it has reverted to the same height as all the other cells. I can see the label is still wrapping but the cell height is wrong.
The standard table views in MvvmCross date back to iOS4 - while the new UITableViewAutomaticDimension sizing wasn't really added until much more recently (iOS8?)
Most real apps tend to use custom cells rather than the standard ones, but if you do want to use the standard ones, then I'd guess you could try adding some code to the setters in the cell which would trigger resize recalculations - e.g. to setters in https://github.com/MvvmCross/MvvmCross/blob/3.5/Cirrious/Cirrious.MvvmCross.Binding.Touch/Views/MvxStandardTableViewCell.cs#L73
I would guess that judiciously placed calls in there to request layout recalc would cause the parent cell and table to redraw.

MonoTouch - how can I pass a value back to my controller from a custom UIActionSheet?

I have a UIViewController with a UITableView. I have implemented a UITableViewDelegate and overridden the RowSelected event to display a custom ActionSheet with UIPickerView i.e. if the user selects a row the ActionSheet displays a list of choices for that row.
What I'm looking to do is ... when the user dismisses the custom ActionSheet (by pressing a Done button), the ActionSheet is dismissed, and the value of the selected item is passed back to the UIViewController for display purposes.
I'm a little unsure as to the best way to handle this. I was hoping someone might have some pointers ?
I think you should subclass UIActionSheet and subscribe to Dismissed and set a property for the value the user selected. (You can also do other work like fill up the action sheet from within the subclass)
Your controller can then subscribe to Dismissed and read your new property.

Java FX 2 Cell Editing, Focus and Text Selection

I am testing JavaFX 2.1 and trying to get editable table views to behave the way I would like them to.
I'm using the example from the JavaFX 2 documentation as a base :http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
The example has 2 problems:
The user is forced to click on a cell 3 times in order to edit it, once to select the row, once to select the cell and make it editable and a further click to focus the TextField
The changes are only committed when the enter key is pressed, if the mouse is clicked outside of the cell, then the data entered in the cell is lost.
On the other hand, one feature that does work correctly, is that I can select text, and re-position the caret within the TextField using the mouse as many times as I like.
There are 2 questions here relating to both of these issues individually:
Java FX 2 Table Cell Editing and Focus
and
javafx 2.1 Updating TableView
When the answer to first question is applied on it's own, I only have to click once to edit the cell (after the row has been selected) and I can still select text and move the caret.
When the answer to the second question is applied on it's own, the edit is committed without the enter key being pressed, but I can only re-position the caret or select text once, if I try a second time, then the edit is committed.
When I apply both answers together, focus is applied successfully and edits are committed when the mouse is clicked away, but I lose the ability to re-position the caret or select text entirely. Any mouse click within the cell commits the edit.
My question is how can I fix the original 2 issues without losing the ability to position the caret and select text?
Try jkaufmann's sample app in his answer to his own question TableView - Better Editing through Binding? His binding solution and implementation of TableView editing semantics seems to adequately address all concerns you raise in your question.
You need to modify the GUI component at the correct time in the spirit of the JavaFX framework. i.e. in the controls layoutChildren method. You need to override the layoutChildren method of the custom TableCell and set the cursor position then e.g.
TextField textField = new TextField() {
private boolean first = true;
#Override protected void layoutChildren() {
super.layoutChildren();
// Set cursor caret at end of text (and clear highlighting)
if (first) {
this.end();
first = false;
}
}
};
I also note that Java 1.8.0_241 also contains this problem in the TextFieldTableCell implementation. Worse TextField is completely private to the TextFieldTableCell implementation, so in order to work around that I chose to copy the source of javax.scene.table.cell.TextFieldTableCell and javax.scene.table.cell.CellUtils. TextField is instantiated in CellUtils, so you can fix the cursor positioning there. e.g.
static <T> TextField createTextField(final Cell<T> cell, final StringConverter<T> converter) {
final TextField textField = new TextField(getItemText(cell, converter)) {
private boolean first = true;
#Override protected void layoutChildren() {
super.layoutChildren();
// Set cursor caret at end of text (and clear highlighting)
if (first) {
this.end();
first = false;
}
};
...
...
}

UIButton has to be tapped repeatedly before touchUpInside fires

I have two UIButtons (start and dismiss), contained by a UIView, contained by an outer UIView.
There is nothing special about the buttons.
This is all done in a xib file.
For one of the buttons, it just works.
For the other, when the code is running (simulator or on the iPad doesn't matter), a touchUpInside message is sent to the corresponding controller only on about 10% of taps. tap-tap-taptaptap-tap...tap-tapFIRE. Sometimes tapping slowly and methodically works better. Sometimes.
When it does finally fire, the message (dismissWindow:) is called/received/processed correctly.
The button has a referencing IBOutlet ("dismiss", although I've tried it both with and without one).
The button, the view and the parent view are all "User interaction enabled" and not hidden.
I've tried with the button both on the parent view, and on the subview.
I've tried with the action set to the view container, and to First Responder.
I've ensured that the button is in front.
Is there some urban legend about dodgy and/or finicky UIButtons on the iPhone/iPad? Am I missing some setting someplace?
The other button on the view, Buttons in other xib files, or those created dynamically work as expected. It is simply this one xib file and this one button.
.h
UIButton *dismiss;
...
#property (nonatomic,retain) IBOutlet UIButton *dismiss;
.m
#synthesize ..., dismiss, ...;
...
-(IBAction)dismissWindow:(id)sender {
[[controller detailViewController] dismissWaitView:self];
[self removeFromSuperview];
}
So I throw this out to the collective consciousness. What can I try?
TIA,
rip
In the end, what I noticed was that the UIButton was of type "custom" and the text was "Done" and the style was "Done". Changing any one of those was sufficient to make the button work as I expected it to.
I changed the text from "Done" to "Finished", and it suddenly started working.

Resources