I have created a UICollectionView subclass which I want to use to provide the keys in a UIInputViewController as a keyboard extension. But I have found that attempting to instantiate a UICollectionView will cause the keyboard to crash whenever the user switches to it. Thinking it might be something to do with my UICollectionView subclass, I tried replacing it with a plain UICollectionView, but this caused the same problem. I even tried just instantiating the object but not doing anything with it, as in the extract below, but it still crashed the keyboard.
// KeyboardViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionView *collect = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
}
I can't get any debugging on the keyboard, because the debugger attaches to the main app's process, so I can't tell what is causing the crash. I would really appreciate any input on whether it is possible to use a UICollectionView on a keyboard extension, and if so, how I can get around this issue.
It turns out that the problem was being caused by simply importing the header for the UICollectionView subclass, even though I didn't use it. When I removed the import, I was able to instantiate a plain UICollectionView and add it as a subview of the keyboard.
This meant I had to do some fairly nasty stuff to abstract the delegate and datasource methods into a separate class so that they would be reusable, but it works.
Related
I have a UITextfield which is a subview of a UITableViewCell. I have customised the UITableViewCell, where I define the UITextField as a property. In the customised class, I override the UIAccessibilityContainer protocol methods.
However I am unable to set the textfields in my test script. This may be because the UIATableCell recognises its' children as UIAElements and not specifically UIATextFields. I am unable to perform to use the element as receiver for the method setValue.
It seems that the trait setting modulates how UIATableCell recognises its' children. However from the apple docs, a UITextField is best described as having either the UIAccessibilityTraitAllowsDirectInteraction or the UIAccessibilityTraitAdjustable. Neither of these help.
As far as I can tell, I have set the visibility hierachy correctly.
[self.contentView addSubview:self.aTextField];
for (UIView *eachView in self.subviews) {
[eachView setIsAccessibilityElement:NO];
}
[ self.aTextField setIsAccessibilityElement:YES];
[ self.aTextField setAccessibilityLabel:#"textFieldOnCell"];
[self.contentView setAccessibilityElementsHidden:NO];
Have I missed a step in making a UITextField accessible in a customised UITableViewCell ? Any help would be appreciated.
We noticed this problem and worked around it in Illuminator.
The basic idea is to tap the parent element (which should force the keyboard to appear) then use they keyboard to type the desired string.
In the UIViewControllers where I don't use .xib files, I've been creating my UI elements in the viewDidLoad methods. E.g.,
- (void)viewDidLoad {
[super viewDidLoad];
// Setup table
self.tableView=[[UITableView alloc] initWithFrame:self.view.frame];
[self.tableView setDataSource:self];
[self.tableView setDelegate:self];
[self.view addSubview:self.tableView];
// Setup custom cells
UINib *lessonNib=[UINib nibWithNibName:#"CustomCell" bundle:nil];
[[self tableView] registerNib:lessonNib forCellReuseIdentifier:#"CustomCellID"];
}
For the most part, this is working fine. But, in the process of investigating a bug associated with dynamic cell heights, I'm curious: is this the appropriate spot to add my UI elements?
Thanks for reading.
I would say it is the right place, yes. Since this method is only called once for sure and is called before anything of your view is shown on screen. And therefore you don´t risk creating them twice or even more often or too late.
But your layout should be done at a different place - in viewWillLayoutSubviews:
When a view's bounds change, the view adjusts the position of its subviews. Your view controller can override this method to make changes before the view lays out its subviews. The default implementation of this method does nothing.
You could also overwrite the corresponding viewDidLayoutSubviews
Regarding your comment: yes, layout information is not yet present in viewDidLoad, self.view.frame for example is not guaranteed to be the actual frame that your view will be displayed in later on. Further more a frame change by some part of your code would cause your UI to not respond if you set their size and position only on load.
Note: Setting up your subviews via code is far more tedious than just designing them in a storyboard - I would heavily recommend that if you don´t have serious concerns against using them.
I know it is possible to connect an object in a XiB file (i.e button) and connect it to any viewController. I am also able to go to that viewController and programmatically set properties to that object(everything autocompletes fine, it recognizes the object properties) However, when I run the app, the button is unchanged, what gives?
Is there something I'm missing? Is there an additional step that I need to do when using a ViewController that is not the .m file related to the XIB?
Here's part of the code... I don't get any errors!
user.default_sales_rep_id = 2;
if (user.default_sales_rep_id > 0) {
buttonMask.backgroundColor = [UIColor blackColor];
}
You are most likely setting the properties on the button too early. Since you don't specify in your question where this code is located, it's hard to say but I'd guess if you put your code in awakeFromNib it would work.
- (void)awakeFromNib {
[super awakeFromNib];
//code here
}
Any changes to your view that differ from your XIB should be done in this method as it is called after the view is set up from the XIB.
Are you certain you are calling [[UIButton alloc] init] before you attempt manipulating it? I assume you have the button already as an IBOutlet, but if I recall, if you wish to make custom changes to the button, you must still do this.
if scrollview inherits from UIView how come my code below doesn't work?
DOBMonthTextField us an an IBOutlet for a UITextField.
[DOBMonthTextField setHidden:YES];
It stopped working when I made my UIVIEW underneath the text field a scrollview. The text field use to hide when I executed the code above. Now it doesn't hide.
While changing the views in nib files via cut-paste, the IBoutlet connections of those views go missing (disconnected), so you always have to reconnect them after pasting.
Check your connections whenever some code for a view created in nib/storyboards used to work earlier but does not after some modifications.
Because hidden (or its setter, setHidden:) is a property of an instance of DOBMonthTextField, not the class itself. Classes don't have properties in Objective C. Here's an example of roughly what you should be doing instead:
DOBMonthTextField *someInstance = [[DOBMonthTextField alloc] init];
[someInstance setHidden:YES];
I am working on an iOS SDK 4 project with ARC enabled.
My class MyTextView (derived from UITextView with UITextViewDelegate protocol) implements the following static method:
+ (void)showInViewController:(UIViewController*)viewController
{
MyTextView *textEdit = [[MyTextView alloc] init];
textEdit.delegate = textEdit;
[viewController.view addSubview:textEdit];
// Show the keyboard
[textEdit becomeFirstResponder];
}
In one of my view controllers I call the following:
[MyTextView showInViewController:self]
This crashes with warning: Unable to restore previously selected frame. on becomeFirstResponder. Looks like some stack related crash because of some cycle. I am fairly new to ARC. The delegate property of UITextView is defined as assign (shouldn't ARC interpret that as weak?). I know this approach is rather strange memory-wise. However, I wanted to know if ARC can handle things like that. Obviously it can't. Any idea what might be the problem and how to solve it?
I don't think it has anything to do with the ARC and memory management, but just a more fundamental problem that a UITextView cannot be a delegate of itself. It gets locked in a loop. Put a logging message in textViewDidChangeSelection and you'll see it gets repeatedly invoked. Not a memory issue, methinks, but rather just a logic issue with UITextView delegates. Even if you don't do your problematic showInViewController but just create a standard UITextView subclass and try to set its delegate to itself, you'll see the same curious behavior.
old post, but here is the answer:
http://www.cocoabuilder.com/archive/cocoa/282093-uitextview-as-its-own-delegate-infinite-loop-on-keyboard-select.html
or here aswell
self.delegate = self; what's wrong in doing that?