UITableViewCell with labels that dynamically appear/hide using Auto Layout - cocoa-touch

I have a UITableViewCell defined in a XIB with auto-layout enabled. It contains multiple UILabels, one of which often runs to more than one line. I am able to appropriately adjust the height of the cell based on its content. The layout is similar to the example below:
What I would like to now implement is an additional UILabel that may not be present at initial render time, but is then populated when a user presses the action button.
What is the best way to accomplish this using auto layout?
UPDATE:
I am attempting to hide/show the dynamic label by adding/removing a constraint with height = 0, but am experiencing issues related to placement/size of the other labels. I have provided an example project showing these issues here: https://github.com/markdorison/AutoLayoutExample

You can animated the constraint by creating an outlet to it and just changing the constant followed by a call to setNeedsUpdateConstraints - all within an animation block

Related

What Cocoa Views and Controls Will Create Something like Part of the Network Prefs Display (Mac OS)? [duplicate]

This question already has an answer here:
NSTableView with +/- buttons like in System Preferences using only Interface Builder
(1 answer)
Closed 7 years ago.
I'm building an OSX app and want to create a set of controls similar to what's found at bottom of the standard Network Preferences configuration panel. I'm running into some layout problems that I wouldn't have expected.
These are my specific questions:
What contains the 3 buttons so there's similar shading all they way across the row where the buttons are positioned? In particular, what's causing the area without buttons to have shading?
How do you do this without getting a double border where the row of buttons meets up with the table?
I want to do this with an xib file. This may be incredibly simple, but I'm missing something I guess.
I find that if you make a button with style "Gradient" and type "Momentary Change", then it looks like the other buttons but does not respond to clicks, so you can use that as the area after the last button. (The NSMomentaryChangeButton is documented as changing the image and title when clicked, so if you don't use an image or title, nothing should change.)
If you check Refuses First Responder in the attributes inspector, then it will not be possible to highlight this blank button using Full Keyboard Access.
Ken Thomases also brings up the issue of the blank button being shown as a button to Accessibility. One can fix that by using a subclass of NSButtonCell that has just one method:
- (BOOL)accessibilityIsIgnored
{
return YES;
}
I think that's easier than writing a custom view.
As d00dle says, avoid double borders by slightly overlapping things.
Since you want the slack space to have the same background as the buttons, and since the buttons can change appearance from release to release of the OS, the best thing to do is to get the frameworks to draw it like it would the buttons.
Rather than using an actual button as JWWalker suggests, I have used a custom view that leverages NSButtonCell to draw the background. The advantage is that you can be sure there's no chance of getting undesirable behavior. For example, a button could get focus (for users who have All Controls selected in System Preferences > Keyboard > Shortcuts > Full Keyboard Access) so that the user could Tab to it. Accessibility will report the presence of the button through VoiceOver. Etc.
Configure the button cell just like the buttons (set buttonType and bezelStyle). In the view's -drawRect: call [buttonCell drawWithFrame:rect inView:self];, where rect is similar to the frames of the buttons. Since one way to avoid double borders is to make the buttons larger than the view's bounds, you may need to do the same for rect. For example, you might want to use NSInsetRect(self.bounds, -1, -1).
The buttons are buttons... This can be accomplished with a custom view drawing border and the background "shading".
To avoid the double border where the table and the custom view meet you simply align it so they overlap by 1 point (pixel) or avoid drawing the top border in your custom view.
I don't know of any standard object capable of doing this.

IOS 7 Approach for create container with two elements?

So, i am new to xcode and iOS7 and i'm trying to create simple container with two elements inside.
I prefer to make it 100% programmatically. (no IB)
I want to create container with two elements Image and Label.
I want to achieve variable width depends on the text element inside.
Here is example:
Based on user action i want to change text on the fly. Let's assume longer text, and main container have to change width too.
And now the question is: What is best approach to to that?
UIView with subviews or something else i'm just expecting direction.
Code examples with be gratefully appreciated.
Thank you in advance.
What you have described is exactly what a UIButton does automatically: it is a container containing an image and a title (text) and it resizes itself automatically when the text changes.
Let us assume, however, that you want to do this yourself. That is, let's say you want a UIView ("container") containing two other UIViews (subviews). Then we need to discuss this requirement:
Based on user action i want to change text on the fly. Let's assume longer text, and main container have to change width too.
This is not going to happen automatically. You can use constraints (auto layout) to describe the size / position of the subviews in relation to the superview, but it works the other way: the superview changes, and the subviews obey. So you will have to change the superview size manually after you change the text.
You can still use auto layout to help you. Let's say the text is in a UILabel. Well, a UILabel wants to change width automatically when the text changes. So far so good. But you must still change the container view width yourself. You can call systemLayoutSizeFittingSize: to learn what the size of the container should be, using constraints, working from the inside out; but then you will have to change its size yourself to that size.
(You can easily create the view, the subviews, and the auto layout constraints in code.)
If you don't want to use autolayout, then you will just calculate the sizes and positions of everything when the text changes and adjust it all yourself (in code). You can learn the size the label needs to be, to fit its text, by calling sizeThatFits: (or sizeToFit which will actually resize it correctly).

Auto Layout "Add New Constraints" not interactive in Interface Builder

I am updating an application for iOS 7 and have decided to use Auto Layout.
When I try to add constraints to any of the elements in the below screenshot :
i.e. View Controller, Table View, View, Table View Section, Table View Cell, Content View, Label.
I am unable do to so, as no item in the Add New Constraints panel ( as seen below ) is interactive.
(Apart from the Update Frames Item)
In my attempts to resolve this issue I have researched that
"When using Auto Layout you may no longer set the frame of a view directly. This line either has no effect, or it may directly interfere with what Auto Layout is doing."
also
"When setting the contentSize of a scrollview with Auto Layout, the content size is automatically derived from the constraints that you set on its child views."
The problem is still there when I update the ViewContoller code to accommodate this advice.
I had a similar issue. I was able to add constraints for items on a Table View Cell - Content View (e.g. UILabel, UIImageView), once I switched the Table View Cell Style to Custom.
If I added images or UILabels on top of a default Table View Cell type (e.g. Subtitle), I could position them on the Content View, but couldn't set constraints on them.
Changing to Custom Table View Cell Style was the solution for me.
To set the constraints you need to select the items and then set the constraints with either the constraints menu or with ctrl+drag.
However, there is no way to set constraints for a tableViewController as it is a already completely set up.
There might be set Autoresizing Mask as layout in Size inspector.
Try switching it to Constraints:

How to replace a view

Application requires more than one window (Lets call A,B,C). Each window has more than one view (table views, image views as well as web view). Lets say window A has three views (x, y,z) and window B has three views (d,e,f). Application needs to display images of different size on orientation change.
I have achieved the same using gesture event listener and looping through windows for views and replacing the view with new images. The problem I have is when we navigate from one window to other and the orientation changes, the loading of view after looping goes for a toss. Is there a better way to achieve the same ?
Is there a method in titanium like following code to replace a view ?
var self=Ti.UI.currentWindow
var newView=Ti.UI.createImageView({image:'abc.png'})
self.replace(self.children[1],newView )
Unfortunately there is now replace method.
You need to remove the whole view and add it again but this can cause a wrong layout if you have more than one view on a same level. The implementation then depends on the layout which was set (vertical, horizontal, composite etc).
For example in vertical layout removing an item and simply add a new one would remove your specified item but appends the new one at the end since you can't specify in which order it should be added.
If you have a composite layout you can specify absolute positions but adding a new view causes a higher zIndex for this view so that it will hide views that were previously added at the same/similar position.
Why not simply change the image link ?
var self = Ti.UI.currentWindow;
self.children[1].image = 'bcd.png';
Well you could always lock the orientation of your window. But this isnt exactly good practice (especially for iOS).
Generally orientation changes are handled pretty well if you define the width and height of your views to be percentages or Ti.UI.FILL, if you have a composite layout. Check that you are not giving the views absolute coordinates as this could cause layout problems. If you have a vertical or horizontal layout you usually don't have to worry about orientation change, unless you did not nest your views in a main container correctly.
Prasad,
If this is about just ensuring that the images look good on different orientations,you can make use of the different folders provided by Titanium in the android/images folder.You can just make different images for each of the orientations and device sizes.For IOS you can change just the images on orientation change as you are already doing.
https://wiki.appcelerator.org/display/guides/Using+density-specific+resources+on+Android
If you are concernced about the layout there are couple of things you can do:
1.Give all the height or width values in percentages.This way all elements will be re sized once the orientation changes automatically.
2.On each window open check if the orientation is vertical or horizontal by default and accordingly set the image attribute of the imageView.
Ti.UI.orientation
This property will give you the orientation of the window by default.Values of this property could be this
Ti.UI.PORTRAIT
Ti.UI.UPSIDE_PORTRAIT
Ti.UI.LANDSCAPE_LEFT
Ti.UI.LANDSCAPE_RIGHT
Use "if else" and accordingly set the images.

How can I add NSTextView and NSMatrix controls in a single scrollable NSScrollView?

I am new to Mac development.
I want to add three controls in a single Scrollable NSScrollView.
1) NSTextView.
2) NSMatrix.
3) NSTextView.
Please note that text in nstextview can be of dynamic height.... and there should be no scroll for textviews.
here is a screenshot of what I am looking for -
how can I add these three views in nsscrollview? Please help!
Update 1 - can I add these controls in a NSView?
I'll assume you've got a project in Xcode 4 started. Select your project's MainMenu.xib file to begin editing your main user interface.
Start with a window. Drag a custom view into it. Add your text view to the custom view, followed by the matrix, followed by another text view, sizing the views as you go. It's at this point that you also can configure your text views not to display scroll bars. Next, select the custom view. Embed it in a scroll view, and there you are.
The window, custom view, text views, and matrix are selected from Xcode 4's Object Library palette. To embed, choose the Embed/Scroll View command from the Editor menu.
As for the dynamic sizing, you'll have to code for changing the heights of the text views, and so the height of the enclosing custom view. (That is an exercise I leave to you.) Your burden can be lessened somewhat by taking advantage of autosizing to maintain the proper spacing between the three UI elements; you can do this either in Xcode 4, or you can do it using NSView's relevant instance methods.
Good luck to you in your endeavors.