Dynamically create views containing buttons - what about constraints? - objective-c

I want a menu (hidden on the left side of my app) with a variable amount of buttons (depending on the user). I took the app over from another developer and he manually added every view and every button and it is a pain to maintain if you want to add another button in between or change something. So I want to redo it automatically.
But how can I achieve that? Let's say i have on the left x views, each containing an image, a button and a separator (to the button below). So I basically only create one single prototype view, button combo and reuse it for all other buttons. But how do I arrange them so the constraints are correctly set?

I would go with a table-view. Setup a cell with an image and a button, separators come for free in a table-view. Make sure the cell has a delegate for the button call-back or a closure to handle the button tap.
Add a controller/manager to control the number of views based on the user.

Related

Adding A View To An Existing View Programatically

How can you add or replace a view within a view with code? I'm programming for OSX, not IOS.
I am using a drawer that utilizes a custom view. In the custom view I have two boxes, one with a custom set of icons that I want to stay static and another box that has the information related to that button. What I want to do is when a user clicks one of the buttons that the 2nd box view changes to reflect the info for that button.
For example, I have five buttons and the default 2nd box is "Info", if the user clicks the 2nd button in the first box view I want to change the 2nd box to be the "List" box instead while the 1st box with the buttons stays intact.
I'm not sure how this would impact constraints since while the first box is a fixed size, the 2nd box needs to be dynamic so that it fills in the "rest of the space" so that when the drawer size changes with the window size that the 2nd box is taking up the remaining real estate.
Thank you!
I have implemented such a scenario in the past using a tabless NSTabView, and an NSSegmentedControl (for the buttons). The NSTabView has it's -takeSelectedTabViewItemFromSender: action connected to the NSSegmentedControl, using Interface Builder.
In the Connections Inspector, this shows up like so:
This has the effect that the index of the selected NSTabViewItem in your NSTabView will correspond to the index of the selected segment in the NSSegmentedControl.

UIText field does not respond to touch after switching view

In my app, I have a text field that works fine, however after going back to the main menu and then back onto the page with the text field, the text field becomes un-touchable, the keyboard does not show no matter how many times you click it.
Here is a screen shot of the interface http://tinypic.com/view.php?pic=y11sm&s=6
I think I may have to add code or connect an action with the text field, but how?
Thanks for your time.
You can remove subviews that you don't use anymore like #Kim has already told you or if you need these subviews but they are blocking the action, you can bring your textfield to front using,
[your_view bringSubviewToFront: your_textfield];

How to prevent a UIView from consuming user input

I have a simple view hierarchy example.
Obviously the main view space is the primary space the user will interact with. At the bottom I have tabs that can pop up to indicate to the user where he/she is in the progression of the app. Normally, these tabs only take up the space indicated by the "Custom Tabs" rectangle at the bottom, but they can expand all the way up to fill the "Empty Space" box.
In order for the tabs to still be clickable, I had to make the tab view's frame the full rectangle containing both the "Custom Tabs" space and "Empty Space" space. What this results in is that "Empty Space" not being interactive to the user when the tabs aren't popped up, because the input is basically being consumed by that UIView, and not forwarded through the rest of the hierarchy.
I suppose the root of this problem is that both "Main View Space" and the "Empty Space + Custom Tabs" are both subviews of the main window.
Is there a way I can tell the system to forward the user input to the sibling views if the user didn't actively tap on an interactive element? For example, doing something with the touchesBegan, touchesEnded etc. methods that would indicate to the OS that this view did not use the input.
EDIT
Here's another version of the view, demonstrating the tate of one tab being open:
EDIT2
After some simple testing, it would seem that the default behavior is that the top most view gets the input first. This applies even if you have a clear UIView on top of a UITextField. The clear UIView will consume the input, preventing the UITextField from being editable
EDIT3
The way the tabs are supposed to work is the user can tap on a tab (sized as in the first picture), and then it will expand to display a thumbnail view associated with that tab (as in the second picture). The user can then optionally tap the tab once more to close it, and return the size to the original picture. In order for the tab to be clickable when it is open, I have to have the containing view be basically large enough to contain all 4 tabs as if they were open. This results in a lot of empty space in the containing view. This empty space results in essentially dead input space on the screen. If there were a button in the main view space that is covered by the empty space, the user would not be able to click on it. I would like to be able to avoid that behavior, and have that button covered by the empty space still be clickable.
Rather than trying to "forward" touches, I would modify your layout so that the tab view is only as big as the tabs, and change it's .frame to be the larger rectangle in code only when you need it. For example, when a tab is clicked:
CGRect tabFrame = tabView.bounds;
tabFrame.origin.y = top_of_emptySpace;
tabFrame.size.height = height_of_emptySpace + height_of_tabView;
tabView.frame = tabFrame;
then you can add the content you need. when you need it to go away, remove the content then do :
CGRect tabFrame = tabView.bounds;
tabFrame.origin.y = top_of_tabView;
tabFrame.size.height = height_of_tabView;
tabView.frame = tabFrame;
There might be some tweaking required to make the content show up as you like, but this way, when the tabs are minimized, you won't have to do anything extra to make the main view respond to touches correctly.
Ok, this is the way I would do it:
The RootViewController has two views, its main view which takes the whole screen, the one that is added to the window. And the tab view.
Then I would add another view controller (a UINavigationController ideally) to the RootViewController and I would have its view added as a subview of the RootViewController's view.
Any change performed, such as pushing new view controller or anything, would be done to the child view controller.
That way, your tab view would always be showing. To open a tab, you could create a new view that would show on top of the tab bar using an animation or something similar.

How do I properly move a scrollview when assigning a first responder?

I have a form in a UIView which consist of multiple textfields, couple of textviews and two fields that are interacted with by the means of an invisible button overlaid on them. When you click on a textfield, the keyboard pops up for text entry and I added a toolbar on it for navigating to the previous and next data entry (whatever the data entry is, be it a textfield, textview or one of the two special cases that are interacted with a button). Now, when I navigate with between textfields with those buttons everything works fine. My scrollview's content moves along the element that becomes the firstresponder (with the help of a piece of code from stackoverflow that scrolls the view while taking into account the height of the keyboard that hides a good portion of it). Here is a visual example.
The problem arises when I want to switch out of a specific data entry (date) that interacts with a hidden button. I'll give some context first. Those data entries show datepickers (one for the date, another for the time) in action sheets, and those action sheets also have navigating button in a toolbar, like so.
The code from stackoverflow that readjust the view do so in the didBeginEditing delegate methods of the textfields and textviews, so when I assign them first responder the scrollview adjust itself while taking into account the keyboard.
This means that, in the case that I switch into a special data entry, I manually move the scrollview's content so I can view the next element. When I switch from a special entry into a textfield I assume that the previously mentioned code from stackoverflow kicks in and adjust the view. It actually does when I move from the hour data entry (which uses a datepicker in an actionsheet) into the next element which is a textfield. However, when I'm at the date data entry (which is directly before the hour data entry) and press previous to assign the first responder to the textfield above it, the scrollview goes way ahead the text field, like so.
What's important to note is that this problem only occurs when the textfield is not in view. This makes me suspect that I'm incorrectly using the code that readjust the view. For instance, there is a constant in the code that represents the height of the keyboard. I tried changing it from 216 to 260 (so it takes into account my toolbar added on top of the keyboard) but this results in strange black artifacts near the buttom that only occasionally appears.
I'm kind of lost in this bug, and my post is already pretty long. I've prepared an example of my problem in a new project, if any of you could take a look into it I'd be very appreciative.
Here it is

What is the correct UI guideline for an "Action" button in an iOS application on a UITableView per row?

My iPad (!!) app has a table view as the UISplitViewControllers details controller. To trigger various actions I use the following:
A swipe gesture on the cells to make a button visible that is called "Action".
Touching the action button shows a UIActionSheet with various options (Delete, Send, Download).
Touching one of the buttons in the action sheet triggers the action.
To achieve this behavior I customized the title of the "Delete" button which would normally be shown by the swipe gesture.
Please note that touching the cell itself will open/preview the touched item.
However, my test users complain that they cannot find the action menu because they would never try swiping the cells and if they would, they would do it to delete the entry. But they like that touching the cell previews the item.
Hence my question: what is the correct way of doing it? Show a disclosure button in every row (the little blue arrow to the right)? Show UIBarButtonItem in every row to bring up the action menu?
I'm so against it because it looks ridiculous to have a button in every row.
Sounds like a tricky situation; I'd either:
Add a detail disclosure button to each cell, and have that push a new view controller with the options (like the YouTube app).
Show the options in the "entry" view and have the "swipe" action an extra, discoverable feature (like the Twitter app).