Rearrange subviews in UIScrollView like App-Icons on Home-Screen - iphone

Hej folks,
I got a question to you: I got a UIScrollView in my application containing numerous subviews (all direct subclasses of UIView). Now I want to give the user the possibility to rearrange these subviews inside the scrollview. Is there anyway to make it look like the way we all can change the icons on our homescreen (auto-rearrange)? I would really appreciate any help!
Thanks in advance,
Tim

Unless you use some custom tool kit (I'm not sure there exists a custom tool kit or API to achieve this), I think you should create them from scratch.
I'm also creating very similar thing you said. In an UIScrollView instance, I added small subviews and can order them only vertically by dragging. Also, I can take any subview to the outside of an UIScrollView instance. (a little bit tricky)
There are two ways to build them. (small subviews == icons)
1a) Implement touch events(gestureRecognizer or touchesBegan, Moved, Ended, Canceled) in a main subview of UIScrollView that contains many small subviews.
1b) Implement touch events in each small subview.
I chose 1b because I want to use small subviews not only in UIScrollView but also anywhere in my program. But with 1b, it was a little bit hard to prevent multitouch among these small views. Also I felt that with 1b, touch events in small subviews are more free from the complicated responder chains of an application.
2) Create a NSMutableArray instance that contains a list of small subviews.
3) Implement a function that displays a NSMutableArray instance onto a main view of an UIScrollView instance by enumerating it.
4) Implement a function that enumerates a NSMutableArray instance and checks whether a current touch position of small subview is in a frame of any small subview of a NSMutableArray. (or checks whether a current moving small subview's frame interesects a frame of any small subview) You can use CGRectContainsPoint or CGRectContainsRect functions from CGGeomtery.
5a) If yes, then you can just change frame of every small subview of a NSMutableArray.
5b) If the user releases a finger outside of frame of any small subview, then do nothing.
Simply using block-based animation methods(iOS4 and later) or begin/commit animation methods, you can create them like a home screen.

Very Good Example For Scrollview with Pagecontrol like iphone home Screen
https://github.com/jarada/myLauncher

Related

UIScrollView or custom drawing

I am facing the following problem in my current project: I want to implement something like the following:
Source: https://github.com/NOUSguide/NGVaryingGridView
Since I have to draw an EPG for maybe 40 Stations or more for maybe a week, my question is: Should I fill a UIScrollView with many many subviews (representing the shows) or is it better for the performance if I draw one big UIView using Quartz2D and then add it as a single subview of the UIScrollView?
Hope you could follow me,
Thanks in advance,
Christian
Im not sure i understand, but you can create a ViewQueue where subviews can be reused, like a UITableView:
Everytime you need a UIView, you ask the Queue(NSMutableArray) to get an existing view. If the Queue is empty create a new UIView, if it already contains views, (re)use an existing UIView stored in the Queue.
Only if the UIView should be visible add it to screen (UIView retrieved from Queue), if its not visible anymore remove it from its superview and add it to the Queue.
You can then use a UIScrollView to show the subviews. If your scrolling you can just set the UIScrollView size to make it larger and smaller.
Hope it helps!

Draggable UIView

I have 4 UIViews inside of a main view controller view. All I need to be able to do is drag the views around the "screen". Is UIScrollView the best option for this, or is there a simpler way?
Apple's Touches sample application contains code that does just this, so you might want to check it out.
UIScrollView should be used for scrolling, not dragging. And the 4 scroll views won't work if they're overlapped so don't even think of using UIScrollView in your case.
A dedicate UIView subclass that overrides -touches*****:withEvent: is needed. See http://github.com/erica/iphone-3.0-cookbook-/tree/master/C08-Gestures/01-Direct%20Manipulation/ for example.

Iphone View explanation in detail (View, Superview, etc)

I'm looking for an in-depth breakdown/explanation of the iphone's view usage. Like, what controllers have what types of views, how they relate (child <> parent), how they can be nested, added and removed, etc.
Preferably something with some pictures would be nice too (I'm a visual learner).
But yeah, in-depth, technical, explanations of the iphone view system when used in IB/Obj-c would be awesome.
Also, feel free to give your breakdown or post to resources and I'll do the research.
Thanks
EDIT:
Ok, I'll be more specific. Is the View a stack - is it a queue? What does it look like when I call addtosubview?
What happens if the view isn't a full UIView, but say a smaller UI Control - will it be visible?
Say I have a UIView with a UITabView (2 items) and one content view is a UITtableView.
What's the parent view? What is the order of the children? Is that all dependent on how I add them to the view? In this case, the UITabBar control takes care of handling the views when I select the button.
When I call insertSubview how do I know what index to position it at?
This will be a good place to start (go from here to UIViewController and others that seem relevant). A UIView can contain many subviews of any type (they all inherit from UIView). To nest views, you add the subview to the superview [superview addSubview:subview]. You should also read up on Model-View-Controller.
Edit:
This SO question might also shed some light on the matter.
Edit edit:
Best I can do to answer your questions:
UIViews have an iVar subviews which is an array of subviews. Each of these also has such an array and can contain UIViews.
I assume you mean not full screen, generally, the topmost view is a UIWindow, and to this you add any UIView subclass you like, such as UISlider.
Your UIView has a subview UITabView, I don't know specifically, but I would guess it has two subviews, one of which is visible at a time, and one of these is the UITableView. Order is dependent on the order you add them in, and they will overlap each other depending on this order, but it can be changed with sendSubviewToBack and bringSubviewToFront.
If you want a specific view order, you're probably better off using insertSubview:aboveSubview: and the equivalent below, rather than at index.
Hope some of this helps.
Ok, I'll be more specific. Is the View a stack - is it a queue? What does it look like when I call addtosubview?
I like to think of it as a tree. The window is the root node, and it has any number of subviews. Those subviews can have any number of their own subviews, going down as far as necessary to create the full interface. The addSubview and removeFromSubview methods manipulate a view's "children".
What happens if the view isn't a full UIView, but say a smaller UI Control - will it be visible?
My understanding is that everything on the screen is a subclass of UIView, even the UIControl objects. Therefore, they behave mostly the same.
Say I have a UIView with a UITabView (2 items) and one content view is a UITtableView. What's the parent view? What is the order of the children? Is that all dependent on how I add them to the view? In this case, the UITabBar control takes care of handling the views when I select the button.
I'm not sure: David's answer has more info that should help.
When I call insertSubview how do I know what index to position it at?
I wouldn't worry about it: most of the time you just want addSubview and you won't care about the internal order.

iPhone SDK view scrolling not rubber banding or using momentum from swipes

I'm having a fundamental problem with getting scrolling to work normally on my iPhone app. I have two views, each created in IB (although I've tried this programmatically and it makes no difference) which scroll very sloppily. Instead of the scrolling that we're used to (which is smooth and continues to scroll and eventually dampen and rubber band at the top/bottom), my scrolling only scrolls as long as my finger is in contact with the view. Swiping down quickly on a view has no more effect than swiping slowly. And when you scroll beyond the top or bottom, the view just stays there scrolled with empty area above/below.
One of my views is a UITableView and the other is a UIScrollView. Both have exactly the same problem and are in different XIBs, coupled to different classes, so this is why I think I'm missing a key concept in general.
My UITableView is a child to a UIView (since there is also a nav bar at the top) with my UIViewController's view connected to the UIView. The referencing outlets datasource and delegate are both hooked to the UITableView. Nothing is subclassed here aside from the ViewController of course which has overrides to populate the table.
In the second instance, I again have a non-subclassed UIView which my UIViewController's view is connected to. I have a subclassed UIScrollView as a child to the UIView and then a have a subclassed UIView (with larger size than the scroll view) as a child to the subclassed UIScrollView. This in itself seems ridiculously complicated to me, but I was not able to get scrolling working at all with fewer than 3 views (again there is a nav bar at the top of the non-subclassed UI-View). I am overriding drawRect: in my UIScrollView, which is putting the content up fine except for this scrolling issue.
Is there something I'm doing wrong organizationally? I've come across many suggestions on stackoverflow and other sites for UIScrollView and none make a difference. And I don't see anyone having scrolling issues with UITableView. I'm not pasting in any code because I would have to post full classes at this point (making the post ridiculously long) and I believe the problems to really lie with the way I'm using IB.
Thanks!!
OK, it turns out that this has nothing to do with UIKit. This code is part of a game I'm developing using cocos2d and that framework is what is causing the problem. For those who are developing on cocos2d, you cannot use FastDirector and expect scrolling to work in UIViews. Just remove any code like [[Director sharedDirector] useFastDirector] and everything will be fine.
Some code might help narrow down your problem.
In the mean time, try creating a new project in Xcode using the 'Navigation-based Application' template and take a look at how the navigation controller is being created in MainWindow.xib. Take a look at how the UITableViewController subclass called 'RootViewController' is defined and how the corresponding xib is setup too. You'll notice there is no UIScrollView explicitly defined anywhere but you get scrolling functionality from the tableview controller 'for free'.
This should give you a pretty good starting point down the right path. I question the need for overriding drawRect: without seeing some code or fully understanding your goal.
Take a look at:
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIScrollView_Class/Reference/UIScrollView.html
http://developer.apple.com/iPhone/library/featuredarticles/ViewControllerPGforiPhoneOS/UsingNavigationControllers/UsingNavigationControllers.html

How to display a progress indicator overlay/HUD on iPhone?

I want to display a progress indicator in a semi-transparent box that floats over a table view. In other words, when the table contents are being downloaded, I want an "Updating" label to appear over it.
I have seen this in several apps in the store, notably Facebook (when you shake to reload) and Darkslide.
My first impulse is to create a semi-transparent UIView, place a UILabel and a UIProgressIndicatorView inside it, and add it to the view hierarchy... but where? A UIView may not overlap its siblings, so I can't make it a subview of the window. I also can't make it a subview of the table, because then it will scroll up and down with the table content.
I thought about creating a new UIWindow, but the documentation basically says don't.
I know CALayers can overlap each other, so that would be an option, but I can't put a progress indicator inside a CALayer, can I? Should I roll my own progress indicator that animates a CALayer instead of a UIView?
I'm not interested in hearing about private APIs.
Edit: The question was based on a faulty assumption. NSViews (on Mac OS X) may not overlap, but UIViews on the iPhone may.
I've just posted a HUD version of mine :
https://github.com/y0n3l/LGViewHUD
you can get this result very easily :
#import "LGViewHUD.h"
....
LGViewHUD* hud = [LGViewHUD defaultHUD];
hud.activityIndicatorOn=YES;
hud.topText=#"The longer....";
hud.bottomText=#"The better !";
[hud showInView:self.view];
Once the task is ended, just invoke
[[LGViewHUD defaultHUD] hideWithAnimation:HUDAnimationHideFadeOut];
and that's it !
You can definitely overlap views. Just add the transparent overlay as a subview in the tableView.
From UIView's documentation:
UIView objects are arranged within an UIWindow object, in a nested hierarchy of subviews. Parent objects in the view hierarchy are called superviews, and children are called subviews. A view object claims a rectangular region of its enclosing superview, is responsible for all drawing within that region, and is eligible to receive events occurring in it as well. Sibling views are able to overlap without any issues, allowing complex view placement.
Also there are the quite famous MBProgressHUD & SVProgressHUD
They are the same kind as #yonel 's HUD
Example
[SVProgressHUD show];
[SVProgressHUD dismiss];
MBProgressHUD seems now more popular (if we base on github stars)
Any object that lives in your MainWindow.xib can get access to the application window via an outlet. The application delegate in the standard projects already has it, but you'll probably want to add the outlet to your view controller that needs to show the progress overlay.
Since in UIKit the UIWindow is a UIView (unlike NSWindow vs. NSView in Cocoa), you can simply add your progress view as a subview of the window:
[window addSubview:progressView];
progressView will cover the entire application UI.
This example uses the technique to fade out the Default.png splash image:
http://michael.burford.net/2008/11/fading-defaultpng-when-iphone-app.html
With relation to the recent edit, as of MacOS X 10.5 Leopard NSView overlapping is deterministic (they always could overlap, you just got undetermined results), though it has a different front-to-back ordering depending on whether the containing view is layer backed or not. This is most likely a side effect of integrating CALayers into the OS X view system.
Answer: Apples docs are pretty awesome.
http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
Currently I'm into over laying transparent views (at least on the back of a napkin at this point). You can use them to hold menu buttons, move them in 3D space, just get nuts.
I mean is this a religious tract of or what? Amazing stuff from the guys at NEXT:
UIView objects are arranged within an UIWindow object, in a nested hierarchy of subviews. Parent objects in the view hierarchy are called superviews, and children are called subviews. A view object claims a rectangular region of its enclosing superview, is responsible for all drawing within that region, and is eligible to receive events occurring in it as well. Sibling views are able to overlap without any issues, allowing complex view placement.