IOS 7 Approach for create container with two elements? - cocoa-touch

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).

Related

Replace label in LineLimit with image for ios-charts

I have a line limit with a label. I would like to replace that label with an image. I realize the ios-charts library can't do that directly but was looking for some insight on how to do this.
There are several ways to do so:
Add the image outside of the ios-charts system, you can calculate the position of the image, and add it there;
You can subclass the ChartLimitLine, add a new property called UIImage, and then you can use it. You may subclass the chart view as a child chart view, and you can add your child limit line there, and then add the image to the view.
If the image is not complicated, such as simple lines and dots, you can choose to manually draw the shape using CoreGrahpics.
It's quite flexible for you to choose a proper way to do that. Just remeber you only need the origin point and the size, then you can add your image wherever you want.
Doing customization requires you understanding OOP and ios-charts in depth.

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.

Is there a tutorial somewhere about designing a really large view and put it in scrollView using storyboard

The question may be similar with
Designing inside a scrollview in xcode 4.2 with storyboards
but none of the answer there makes sense at all.
Okay I created a new controller and I added a scrollView.
The very first thing I noticed is there is NOWHERE to specify the content size of the scrollView.
Not in attributes inspector, not in size inspector.
Then what?
I am expecting some larger than normal box where I can draw all the view I want to put in. There is no such thing either.
I am very frustated.
All the "tutorial" out there tell about how to fill scrollView using code.
Another thing I tried is to select controller go to size inspector and then choose FREEFORM.
Great. I still can't make that template big.
Should I do this in XIB instead? At least on that one I can have one huge UIView. Or what is the official way industry standard way of doing this? Is there a WWDC for this one?
Say I want to draw something like these:
I don't think you can get a tutorial on this as it is simply impossible in IB. As most people already commented out what you want to do here need to be done programmatically.
If you are using XIB you can set up all your content there. Under the size tab (in the inspector) you will need to change the height to fill all your content but you still need to set up your contentSize programmatically.
For storyboard I don't think it is possible to change the size of your scrollview in IB.

Change size of window in Cocoa?

I have a window whose size I need to change when the user clicks on it. I am using [self setFrame:windowFrame display:YES animate:YES] to accomplish this.
Even though the window successfully changes size (I increase its height), it moves the contents of the window up with it. How do I prevent this from happening? I want the contents to remain in place.
I am on OSX Mountain Lion developing an app for OSX using Objective-C and Cocoa.
EDIT: Constraints and/or Springs and Struts will not work as I need to move the contents around after the window is resized.
Constraints and/or Springs and Struts will not work as I need to move the contents around after the window is resized.
In that case, you should use NSViewAnimation.
A single view animation can actually perform multiple animations to multiple views, and you can even do one to a window, despite the class's name and the fact that windows aren't views in Cocoa.
You create a view animation with initWithViewAnimations:, which takes an array of dictionaries. Each dictionary identifies the target (NSViewAnimationTargetKey) and what to do to it: Either change the target's frame (NSViewAnimationStartFrameKey and NSViewAnimationEndFrameKey) or fade the target in or out (NSViewAnimationEffectKey). For your case, you'll be changing the targets' frames.
When the user does the thing that causes the resize of the window, you'll need to compute the desired overall size of the window (taking care to adjust its frame's position so it doesn't grow off the screen), as well as the new frames—both positions and sizes—of your views. Everything that will move and/or change size, create a dictionary for it and throw it into the array. Then create the view animation.
An NSViewAnimation is a kind of NSAnimation, which provides all the methods for starting and stopping the animation, monitoring its progress, hooking into it, and chaining multiple NSAnimations together. If nothing else, you'll need to start the animation.
If you are using the Interface Builder to build these views, then I believe one approach is to set the "struts and springs." These are available under the "size inspector" and are the red arrows and bars above the "autosizing" label. Play around with these to get the effect that you want, but the general idea is that the arrows control how the size of the view adjusts to changes in the size of the parent view, and the bars control the relationship of the edges of the view to the edges of the parent view as the size changes.
In constraint-based layout, set the views around the edge of your window to be a fixed distance from their superview's edge.
Xcode will infer a lot of resizability from that; if anything still isn't resizing properly, adjust its constraints so that its width and/or height is no longer constant.
The easiest way is to move your views until blue lines show up in the editor. Each blue line corresponds to a rule in the HIG about how things should be lain out, and if you drop the view there, Xcode will create constraints matching those guidelines. For example, if you set a view 20 points from the right edge of its superview, you'll get a blue line for that, and if you drop the view there, you'll create a constraint that the view must remain that distance from that edge.
The superview isn't the only view with which you can create HIG-based constraints. You can also create guideline constraints between sibling views. For example, if you put a button next to another button at the appropriate distance, you'll get a blue line across that distance, and if you drop it, you'll create a constraint that those two buttons must remain that distance from each other.
If you want to do something really custom, the three buttons in the lower-right corner of the nib editor will let you create any constraint you want. What you have selected determines what constraints you can create; the nib editor's outline view will help you make sure you have the selection you want.
You are going to have to iterate through all of your subviews and change their frame positions based on the delta of your window frame.
so if you expand your window frame by 20 in all directions, all your subviews are going to have to increase their frame positions by (20,20) to offset the windows movement.

Programmatically added UI items order next to each other

There is a UIScrollView and I'd like to programmatically put subviews in it. It's ok, but how can I lay automatically the subviews next to each other?
Thanks in advance!
You can't. The view hierarchy in UIKit--like the view hierarchy in most UI frameworks--uses explicit layout.
Your comment asks about HTML-like floating; the box model stuff that HTML/CSS uses was designed to serve a very different goal (flowing document layout) than what UIKit is for, and so there's no real analogy in the framework.
UIViews do support automatic re-layout on resize/frame change of the parent view (you can say whether a subview should resize, how, and where it should be "pinned" to), through the autoresizing mask property, but I don't think that's what you're asking for.
You could, if you were inclined, build a set of methods, perhaps as a category on UIView, that let you add subviews that had their frame origins adjusted automatically based on existing subviews.
The position of the subviews is dictated by their frame property. So you need to set their frames such that they line up next to each other.
If they are all the same size you can do with some simple math and CGRectMake(). If they will have different sizes, you can use CGRectDivide() to break a large rect into smaller rects. CGRectInset() is also useful, in case you want some padding between them.