How do Ioop through all controls and act on certain ones? - iphone

I have an iPad application that adds buttons at runtime based on where the user touches within the view.
Now - I need to remove all these buttons at once.
I have set the tag of each button to be very high and grouped by type of button that was dropped.
How do I loop through all the button on the view and remove them if they fall into the right classification??

This removes all UIButtons. Adopt it to your needs. If you want to use tags I would recommend to tag every button that should stay in the view.
for (id object in [self.view subviews]) {
if ([object isKindOfClass:[UIButton class]]) {
[object removeFromSuperview];
}
}
Or you could add each UIButton to an NSMutableSet when you create them, and delete every button of the set if you don't need them anymore.

The only tag-based method is UIView#viewForTag and it returns a single object. (I believe it's the last view you added with that tag). But, you can adapt the above code for your purposes:
for (UIView *iView in [self.view subviews]) {
if (iView.tag == TARGET_CLASSIFICATION_TYPE) {
[iView removeFromSuperview];
}
}

Related

iOS: Removing one view from superview causes another to get removed?

This is a very odd problem. I have 5 subviews added to a UIViewController. One of them needs to be removed, but when I do this, one of the remaining 4 subviews is also removed. This necessitates that I re-add it using addSubview. The two views in question are not related in any way.
Is this a known iOS SDK bug? It happens for sure running on the simulator with iOS 6.1.
Thanks.
Here, In Your Question not mention That which Method you use for remove subView so,I give you simple suggestion for remove subView.
Give Tag of Each subView such like,
self.subView1.tag = 1;
self.subView2.tag = 2;
.
.
.
.
self.subViewN.tag = N;
And You can access(Remove) any subView base on its Tag, such like
[[self.view viewWithTag:1] removeFromSuperview];
This tips might helpful for you.
You can remove single subview using the following code.
[subview_Name removeFromSuperview];
if you want to remove all subviews form the view then use this.
NSArray *subViewArray = [self.view subviews];
for (id obj in subViewArray)
{
[obj removeFromSuperview];
}
if you want to remove all subview of particular class then use this.
NSArray *subViewArray = [self.view subviews];
for (id obj in subViewArray)
{
if([obj isKindOfClass:[classname class]])
{
[obj removeFromSuperview];
}
}
example : if you want to remove subview of UIImageView class then replace if condition with this.
[obj isKindOfClass:[UIImageView class]]

iPhone - Keyboard corner button

I would like to make an extra button in the iPhone keyboard left bottom corner like on the photo bellow. Is it possible to do this ?
the only way to customize those buttons is to rebuild the keyboard itself.
http://www.raywenderlich.com/1063/ipad-for-iphone-developers-101-custom-input-view-tutorial
Ray has always got some good tutorials on iphone dev. being able to customize your inputView is only half the battle tho. You will then need to build the custom view. Likely you will want to emulate the existing keypad, with your custom button obviously.
as a side note. to dismiss the keyboard you need to resignFirstResponder via the first responder.
When you get that far, here is the code I use to do exactly that
#implementation UIView (FindAndResignFirstResponder)
- (BOOL)findAndResignFirstResponder
{
UIView *responder = [self findFirstResponder];
if (responder) {
[responder resignFirstResponder];
return YES;
}
return NO;
}
- (UIView*)findFirstResponder
{
if (self.isFirstResponder) {
return self;
}
for (UIView *subView in self.subviews) {
UIView *responder = [subView findFirstResponder];
if (responder != nil)
return responder;
}
return nil;
}
#end
call the if you have a hold of the superview of all your inputs, you can call findAndResignFirstResponder on that view.
Or as you can see the findAndResignFirstResponder calls resignFirstResponder on the "found" firstResponder. therefore if you have the first responder you can just resign it
No it is not. The Keyboard is owned by the system. You can change the kind of keyboard (normal, numeric, twitter etc), but you can't customise it. It is a question which is worth a +1

Creating a custom view in Interfacebuilder and using that in code

I have made a view in the application that shows a UITableView. It will be full of results (obviously) almost all the time, however when it does not have any results I want to show another view that inform the user about how he/she could populate the table.
I want to design that view in the interfacebuilder. I will have to check in the code whether the datasource is empty or not to toggle between the two different nibs. How do I instantiate and configure a view made in Interfacebuilder?
The easies way to do this is by adding the view in xib normally and make it visible
Design your both views, the table view and the other view, give the tableView a tag of 111 for example and give the otherview another tag 222 for example
Now in viewDidLoad
Get both the views
UIView *noDataView = [self.view viewWithTag:222];
UITableView *tableView = [self.view viewWithTag:111];
//Hide both of them or only the noDataView until you know if you have data from the dataSource or not
Check for your data source
//hasElements do you have any element to show?
if(hasElements)
{
noDatView.hidden = YES;
tableView.hidden = NO;
}
else
{
noDatView.hidden = NO;
tableView.hidden = YES;
}
You can load nib file based on condition.You can write category as follows:
self.view = (UIView *)[self loadNib:#"SecondView" inPlaceholder:self.view];
- (UIView *)viewFromNib:(NSString *)nibName
{
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
for (id view in xib) { // have to iterate; index varies
if ([view isKindOfClass:[UIView class]]) return view;
}
return nil;
}
- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder
{
UIView *nibView = [self viewFromNib:nibName];
[nibView setFrame:placeholder.frame];
self.view = nibView;
//[self.view insertSubview:nibView aboveSubview:placeholder];
//[placeholder removeFromSuperview];
return nibView;
}
The other answers give you possible technical solutions but I would propose that if you are using the standard Apple design guidelines, you probably don't even need to worry about it. For instance, somewhere on your screen you should have a bar button item with the identifier "Add" (which shows the plus icon). Then rather than giving a long (often poorly localised) description of how to add items, just have a header for an empty section which says "No items" replacing items with whatever pluralised noun is appropriate for your table's items. For example, for an Archery related app I am working on:
Notice how the Edit button is currently disabled too, thus no explanation is needed as the only thing they can do at this point is tap the Add button (screenshots on the Appstore will have shown them what they can expect to see after this point).

Move buttons down in UIAlertView

I have an app which displays in landscape mode and I've overwritten the height of a UIAlertView with the following code:
- (void) willPresentAlertView:(UIAlertView *)alertView
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGRect frame = [alertView frame];
alertView.frame = CGRectMake(frame.origin.x, 0, frame.size.width, screenBounds.size.width);
}
This almost works. The UIAlertView is taller, however, the buttons in the alertview don't get pushed down.
Does anyone know how I can push the buttons in a UIAlertView down when I change the alert view's height?
I think it is more elegant and less risky to replace UIAlertView with some independent AlertView instead of messing around with it.With independent I mean not inheriting form UIAlertView.
TSAlertView is such a replacement.
http://dl.dropbox.com/u/47535/TSAlertView/1-thumb.png
http://dl.dropbox.com/u/47535/TSAlertView/3-thumb.png
http://dl.dropbox.com/u/47535/TSAlertView/2-thumb.png
I'm guessing that you'll probably have to subclass / manipulate the UIAlertView class to achieve that, which can be risky as Apple can change their implementations so wrap your code in appropriate checks.
A start would be to do:
NSLog(#"UIAlertView subviews: %#",alertView.subviews);
That'll print some output for the various elements making up the UIAlertView, you will probably see a few UIButtons in there which you can then manipulate by using something like:
UIButton* button1 = (UIButton*)[alertView.subviews objectAtIndex:N];
[button1 setFrame:CGRect(button1.frame.origin.x, button1.frame.origin.y+10, button1.frame.size.width, button1.frame.size.height)]
A sensible check would be to confirm that the objectAtIndex is the correct type of element before you perform operations on it, this isn't foolproof however as Apple could add more UIButtons or something..
if ([[alertView.subviews objectAtIndex:N] isKindOfClass:[UIButton class]]) {
...
}
Depending on your situation you may also want to iterate over the subviews array and move all UIButtons down rather than just hardcoding in some specific objectsAtIndex but that's a whole other answer. :-)
This link should help. In my opinion, I would not try messing around with the view hierarchies. This can lead to rejection from the App Store. Either build a new AlertView from scratch, or leave it as it is.
NSArray *subViewArray=[alertView subviews];
for (NSUInteger ind=0 ; ind < [subViewArray count]; ind++) {
if ([[alertView.subviews objectAtIndex:ind] isKindOfClass:[UIButton class]]) {
UIButton* button1 = (UIButton*)[alertView.subviews objectAtIndex:ind];
[button1 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y+100, button1.frame.size.width, button1.frame.size.height)];
NSLog(#"button1.frame.origin.y=[%1.0f]",button1.frame.origin.y);
}
}

How to remove everything fron the superView and not just the last item?

In my app i had to draw certain checkboxes at a same time and i used a single function to add all of them. Now when a user clicks one of them all of those checkboxes should get removed from the superview and currently its just removing the last one. Also i have issue to recognize those checkboxes like which one is clicked. i know it should be done through Tag property but don't know how exactly it should be implemented.
Any suggestions.
Removing all subviews
int numberOfSubviews = [[yourView subviews] count];
for(int i=0;i<numberOfSubviews-1;i++
{
[[youView subviews]objectAtIndex:i]removeFromSuperView];
}
//this will leave check box that you added at last.... for first one to remain loop from 1 to numberOfSubviews....
Using tag property...
when you are creating checkbox objects use
checkBoxObject.tag = i;
//I am considering i as looop count which you are using in a loop
to add checkboxes.
then whenever you need a object of checkbox
[yourViewonwhichYouAddedCheckBox viewWithTag:<your tag >];
Thanks
For identifying a "checkbox" or better said any view within an action-method:
- (void)someActionHandler:(id)sender
{
UIView *actionOriginView = (UIView *)sender;
NSLog(#"this action came from view:%d", actionOriginView.tag);
}
For assigning the tag, you may use the IB or within your code, while instantiating;
UIView *myFunkyView = [[UIView alloc] initWithFrame:CGRectZero];
myFunkyView.tag = 1337;
For removing a bunch of views from your superview - lets assume their tag is set to 10 - 15;
for (int i=10;i <= 15;i++)
{
UIView *childView = [superview viewWithTag:i];
[childView removeFromSuperview];
}