Automatic view id's like in android - ios

I need to write some gui for IOS, yet i am so used to the automatic view id's that android has, that i am at a loss when it comes to identifying views without putting explicit tags in the interface builder
is there some way to automatically identify iOS views from interface builder or otherwise ?
maybe a library that does that ?

Thats why you have IBOutlets. Create an IBOutlet for your views, like so IBOutlet UIView *view1; etc etc then in link the IBOutlet to your view in Interface Builder. Now you can progammatically use the view1 variable which will modify your view associated to that IBOutlet in interface builder\
UPDATE
Progammatically create all your views like so:
for(int i = 0; i < 20; i++){
//set your x and y coordinates with some awesome maths, maybe you want to create a grid, so update the x coordinate accordingly
UIView *view = [UIView alloc] initWithFrame:CGRectMake(whateverframe)];
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
[imageView addGestureRecognizer:singleTapGesture];
[singleTapGesture release]; //remove line if you have an ARC project
view.tag = i; //this is just for you since you like to handle your views with id tags
}
Then your one method that will handle the taps for all your code
- (void) viewTapped:(UIGestureRecognizer*)recognizer
{
UIView *viewTapped = recognizer.view; // This is the view associated with gesture recognizer.
int id = viewTapped.tag; //heres the tag id do whatever you like
//do something with either that view variable which will return the view that was tapped
//maybe you wanted to change the color of it or something or change the contents of it
//or you can do something with the id tag of that view.
//or maybe you just want to handle it with if else statements like so
//if(viewTapped.tag == 1) //do this
//elseif(viewTapped.tag == 2) // etc etc
}

Set Tag for each and every view using property setTag and retrieve the corresponding view using – viewWithTag:. [abaseView subViews] returns an array of subviews. Filter the subviews using Class and Tag.

Related

UIContextMenuInteraction for UIControl [duplicate]

This question already has answers here:
iOS 14 Context Menu from UIView (Not from UIButton or UIBarButtonItem)
(2 answers)
Closed 1 year ago.
I know UIButton has a menu property so that context menus can be added to the button. But for other UIControl subclasses, such as custom UIControls, this property does not exist.
I know that one way of adding a context menu to a UIControl is to call addInteraction and then adopt the delegate for the context menu. But then if I have multiple controls on the page, how do I add the menus for all the different controls since they all share the same delegate?
Alternatively, how could I add a menu property to my UIControl subclass? I know that UIControl has a property called contextMenuInteraction and that is apparently automatically populated, but I do not understand how to use that property. I know the control has to implement the delegate method (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location, but then inside that method, do I just construct the UIContextMenuInteraction object? And when the menu property is set, how do I get it to call the delegate method?
Essentially I would like to be able to imitate the UIButton class's menu property in my UIControl subclass. But if not that, then I would like to at least figure out how to support multiple context menus all sharing the same delegate.
You can create and add a new UIContextMenuInteraction object to views (or controls, etc) in the same way you add a new gesture recognizer.
Then, in your menu action handler, you can get the view that was long-pressed to show the menu via the .sender:
UIAction *someAction = [UIAction actionWithTitle:#"Some Menu Option"
image:nil
identifier:nil
handler:^(__kindof UIAction* _Nonnull action) {
// get the view that presented the context menu
UIView *v = ((UIContextMenuInteraction *)(action.sender)).view;
// do something
}];
So, if I have a custom UIControl called MySwitch, and I want to add 7 of them to a stack view, giving each a context menu, I could do something like this:
for (int i = 1; i < 8; i++) {
MySwitch *v = [MySwitch new];
[v setTitle:[NSString stringWithFormat:#"Switch: %d", i]];
[v.heightAnchor constraintEqualToConstant:60.0].active = YES;
UIContextMenuInteraction *interaction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
[v addInteraction:interaction];
[stack addArrangedSubview:v];
}

ios-Update multiple UIViews on UIScrollview

I have a ViewController that contain a UIScrollView, that contains a few views which are custom UIViews (very simple uiimage + uibutton) that the user can scroll between (one custom view at the a time).
I want the user to be able to "mark" a photo, and then to display a certain text, when the user select a different photo (by using the button), I want to update the text on the previous selected photo and the current selected.
What should I do?
Inside the view itself I don't have access to the previous view, I figured I should send a notification to the view controller but than I have no access to the button I want to update
You could use tags to identify the scrollViews subviews.
Add a tag to the subview and the same tag to the button that belongs to the subview while adding them to the scrollView.
view.tag = 1;
button.tag = 1;
Then in the method called by the buttons, you can use the buttons tag to get the according custom view.
-(void)buttonClick:(id)sender{
UIButton *btn = (UIButton*)sender;
NSInteger tag = btn.tag;
UIView* customView = [self.scrollView viewWithTag:tag];
}
To access the prevoius selected view, store the tag of that view when editing for the next call of the function.

Dynamically create UIButton based on response from server

I need to implement a view that require me to create a buttons based on the response from the server.
Example response:
{
...
"enable_button_1" = 1;
"enable_button_2" = 1;
"enable_button_3" = 1;
...
}
Currently, I try to create the buttons manually using Interface Builder. And each of them are embedded in UIView and put on top of each other. Like so:
They are hidden by default. So, whenever on or more buttons enabled, I will check using if conditions and then unhide the view.
eg. only one button enabled
eg. two button enabled
But the thing is by doing so, I would probably miss a few use case and this seems like a bad practices. Is there any way that I could create it dynamically instead of creating multiple buttons in UIViews in Interface Builder?
You can always create buttons programatically and add them to your view. You'd have to calculate the width of the button-frame so that they always fit the view 100%.
For example somehow like this:
//Here you'd have to calculate the correct position of the button you want to add
CGRect frame = CGRectMake(0, 0, self.buttonView.frame.size.width, self.buttonView.frame.size.height);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button setTitle:#"myButton" forState:UIControlStateNormal];
[self.buttonView addSubview:button];

Add custom UIView programmatically created inside XIB UIView

I've created a UIView programmatically that embeds several UIControls (UIButtons, UISwitchs and UILabels mainly). I set in the -(id)initWithFrame: of this class the background color.
I have created a message to add the UIControls in the view in order to put inside of my custom view. It's something like that:
-(void) CreateGuiObjects
{
UIView *container = self;
//create uiswitch
mOnOffSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(10, 20, 0, 0)];
mOnOffSwitch.translatesAutoresizingMaskIntoConstraints = NO; //used for constraint testing
//add parent view (self)
[container addSubview: mOnOffSwitch];
/*
other stuff like above
*/
}
then in my view controller there is an event handler for an external button; the action is to add the above custom view in an empty UIView created with Storyboard Interface Builder in Xcode.
the code is like the following:
-(void)CreateButton
{
MyCustomView *view = [MyCustomView alloc] initWithFrame:CGRectMake(20,20,300,200)];
[self.view addSubview: view];
//now call my create method
[view CreateGuiObjects];
}
now, the problem is that it draws the controls, but it seems to position them in a different place...i set the frame origin for the container view in (20,20) and then put the switch in (10,20) where this point is relative to the custom view origin. Instead of that position the view seem to be far away from that position and the second problem is that the background color (gray) set in the initWithFrame is totally ignored.
If i remove every call to addSubview inside the CreateGuiObjects, it draws the empty view with the correct background color and in the correct position.
Edit:
if remove `mOnOffSwitch.translatesAutoresizingMaskIntoConstraints = NO; it works fine...but if i put again it doesn't work. Need to understand deeply the meaning of this property.
Could someone can help me? i think it is a silly question but i'm new to iOS development :(
thanks in advice
Method translatesAutoresizingMaskIntoConstraints = YES means that the UIView is using Auto Layout.
The fundamental building block in Auto Layout is the constraint.
Constraints express rules for the layout of elements in your
interface; for example, you can create a constraint that specifies an
element’s width, or its horizontal distance from another element. You
add and remove constraints, or change the properties of constraints,
to affect the layout of your interface.
When calculating the runtime positions of elements in a user
interface, the Auto Layout system considers all constraints at the
same time, and sets positions in such a way that best satisfies all of
the constraints.
read more about Auto Layout Concepts
If you don't know how to use Auto Layout I would recommend you to turn it off.

ios custom navigation (vertical) advice

I have an idea for an ios5 navigation I'm doing on an app and I thought it wise to get some constructive criticism from SOF about my idea.
Idea:
UIView containing 6 or so buttons stacked vertically
UIButtons have a selected state.
Buttons static/global keeps track of last touched button and always resets the last touched button when a new UIButton is touched.
Question:
Can you read and access the children of the UIView?
eg. (pseudocode)
for (i in [myView children]) {
[[myView getChildAt:i] doSomethingToThisButton];
}
Thanks all!
Yes. Here's the non-pseudocode (well, mostly):
for (UIView *subview in [myView subviews]) {
[subview doSomethingToThisButton];
}
Or, if you prefer
for (int i = 0; i < [myView.subviews count]; i++) {
[[myView.subviews objectAtIndex:i] doSomethingToThisButton];
}
Don't make your last touched button a static variable because then you can only have one such control in your whole app. Make a UIView subclass to act as the container for your buttons, and have the last selected view be a property of that class.
You may also want to make your containing view a subclass of UIControl instead of UIView, then you can make it send events and bind to it using drag and drop in interface builder, just like a regular control (e.g. a button).

Resources