I'm trying to make a bunch of buttons behave somewhat like float:left in CSS.
So whenever the view changes size, on orientation change for example, the buttons should adjust so they fit within their container view.
In landscape mode, this UIScrollView should scroll horizontally, in portrait mode, it should scroll vertically.
I'm trying to make an ScrollView similar to the "Featured" tab in the iPad YouTube app. Landscape has 4 columns, portrait: 3 columns, "Subscriptions" tab, portrait, the same view has 2 columns.
I have implemented a layout system to do things like this. There is a demo project on how to use it checked into that repository. I'd be happy to answer any questions about it. This is much more lightweight than AQGridView, so if you don't need the extra functionality he is providing, I would recommend an approach similar to mine.
you might want to check out AQGridView, which is basically a re-implementation of Cocoa's NSCollectionView: https://github.com/AlanQuatermain/AQGridView
Otherwise, you might need to override layoutSubviews in your parentView and then rearrange the subviews (buttons) accordingly when the dimensions of the parentView change.
Cheers,
Johannes
If you had to implement this manually (by overriding layoutSubviews), I think the algorithm would be something like this:
Start with X = 0, Y = 0 (assuming flipped coordinates)
For each button:
If (X + button width) > container width, set X = 0, increase Y
Place button at (X, Y)
Increase X by button's width
Related
I am attempting to implement something similar to Safari where the window's style mask is set to NSFullSizeContentViewWindowMask so the NSToolBar and title bar blur the background view.
This works fine, however I have a view that I need to not be clipped by the toolbar/titlebar, similar to how Safari's WebView has an initial top padding that doesn't cover the content when the view is unschooled.
My attempted solution was to create a dummy NSView which the unclipped views align their top value to, then changing the height constant of the dummy view to the height of the titlebar/toolbar. The issue, however, is that there seems to be no way to calculate the height of the toolbar.
This suggests that I calculate the height by subtracting the height of the contentView from the height of the window, but that only works (returns 0 otherwise as the two heights are equal) if I don't use NSFullSizeContentViewWindowMask which I want to use for the blurring effect.
Am I overlooking something simple, or is there no simple way to accomplish this?
Check NSWindow's contentLayoutRect property.
In Android, when you add subviews to the horizontal LinearLayout, you would see that all the subviews would be aligned horizontally.
|subview1|subview2|subview3...
In iOS, how do I achieve this?
I have a UIView as the parent view, but when I add subviews, it would get stack on top of each other. How do you use UIView.addSubView such that all the subviews would align horizontally?
One way, that I am attempting now is changing the frames.origin.x of each subviews
for example
subview1.origin.x = 0
subview2.origin.x = subview1.origin.x + subview1.size.width
subview3.origin.x = subview2.origin.x + subview2.size.width
...
Is there better ways? thanks, and would appreciate any suggestions, or comments.
Using the Auto Layout feature, which can be done from the interface builder GUI, or else programatically:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/AutoLayoutinCode/AutoLayoutinCode.html#//apple_ref/doc/uid/TP40010853-CH11-SW1
Yes, u r doing in right direction - you will have to change view's frame manually. there are convinient API for that:
subview1.origin.x = 0
subview2.origin.x = CGRectGetMaxX(subview1.frame);
subview3.origin.x = CGRectGetMaxX(subview2.frame);
Take into consideration that constraints are available form ios 6.0
Either:
AutoLayout as suggest in another answer if using Interface Builder (Nibs or Storyboards).
AutoResizingMasks by aligning them once and setting flexible top and bottom margins.
Manually by using UIView's center property.
CGFloat centerY = ...;
for (UIView * view in superview.subviews)
{
view.center = CGPointMake(view.center.x, centerY);
}
As of iOS 9 you can use UIStackView, which works very similarly to LinearLayout: you add views and the stack view arranges them as needed based on your sizing option. If you're using Interface Builder you can experiment with each of the options to see which one suits your needs. You can also set spacing between views in the stack view, adding some padding.
For your particular needs, use stackView.axis = UILayoutConstraintAxisHorizontal; to make your views line up horizontally.
WARNING: When adding stack view child views in code you should always use addArrangedSubview() like this:
stackView.addArrangedSubview(someView)
If you try to use plain old addSubview() it won't work correctly, because the stack view won't know to arrange it.
As for removing, you need to be careful to use stackView.removeArrangedSubview(someView) and someView.removeFromSuperview() otherwise the view won't be removed correctly.
You might find my UIStackView tutorial useful.
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.
I have an image inside a UIScrollView. What I want to happen is if I zoomed in to a particular position, I want to disable the scrolling (both vertical and horizontal) so that it will remain on the zoomed area. Can you give me any ideas on how to do this?
Two things to keep in mind:
Make sure you are exactly where you want when you need to disable the scroll. (you can use some methods from the UIScrollViewDelegate to accomplish that).
Make the contentSize of your UIScrollView the same size of your frame. This way both the horizontal and the vertical scroll will be disable.
CGRect myScrollViewRect = myScrollView.frame;
CGSize myScrollViewFrameSize = CGSizeMake(myScrollViewRect.frame.size.width, myScrollViewRect.frame.size.height);
myScrollView.contentSize = myScrollViewFrameSize;
For clarity I putted more code than you would normally need to.
I have a view-based NSTableView which is embedded in an NSScrollView. It has custom cells that are x number of pixels high. The NSScrollView is the same size as the panel that it is a subview of. I want to resize the entire NSTableView depending on how many rows are in the table.
Everything is working except the resizing. Resizing the scroll view manually in IB seems to have the desired affect, but NSSrollView does not seem to have a class method to resize its view (like NSView has setFrame). Should I be resizing the scollview, the tableview, both, or something else? Does NSScrollView have a setFrame method or similar that I am missing?
Thanks.
Before you try to do it programmatically, make sure you have the outline view's autosizing masks set up properly in the nib file. It sounds like you simply want the outline view (and its scroll view) to always remain the same size as the window that it's inside.
By default, the autosizing masks of an NSScrollView/NSOutlineView combo that you place into a window looks like the following:
In other words, it's set up to always remain the same size as it is now, no matter how large you resize the window to be.
What you want to do is to change the autosizing masks to look like in the image below:
To do that, you click in the white autosizing box wherever there's a dotted red line to toggle it into a solid red line. Once it's configured that way, the scroll view (and table view) will always (automatically) be resized to be the same size as the window that it's in.
There may also be a way to achieve this using Lion's new "auto layout" feature, but I'll have to leave that to someone who has more experience with it.
In case you really need to do this (such as when you want all rows to fit in the scrollview alleviating the need to scroll) and the scroll view is only a portion of the window/view you can do:
[[myTableView enclosingScrollView] setFrame:newFrameRect];
scrollview.frame = CGRrectMake(x, y, w, h);