I'm working on an an app that updates both a UITableView and a UIScrollView. I like how UITableView updating works. As I add, remove, or update items, I call insertRowsAtIndexPaths:withRowAnimation:, reloadRowsAtIndexPaths:withRowAnimation:, and deleteRowsAtIndexPaths:withRowAnimation: as appropriate. However, updating the UIScrollView has turned out to be more of a challenge.
So how can I do it? My UIScrollView contains images, and I want to be able to insert, update, and remove individual images -- with animation -- efficiently and smoothly, and perhaps in random order. How does one do this sort of thing?
As an example, I have code like this in my UIScrollViewDelegate implementation for adding a new image:
if (newImageindex == currentImageIndex) {
[scrollView setNeedsDisplay];
[scrollView setContentOffset:portalView.contentOffset animated:YES];
} else if (newImageIndex < currentImageIndex) {
currentImageIndex++;
CGPoint offset = portalView.contentOffset;
offset.x += portalView.frame.size.width;
portalView.contentOffset = offset;
}
This is close, I think, but not quite right. I end up with the images added, but the UIScrollView seems to scroll to a position before the first image in the view. If I start scrolling it by hand, the first image appears. It's like it's scrolled to position -1 in my images.
The example may not help to highlight my problem much, but surely it's a common need to dynamically rejigger the images appearing in a UIScrollView. What's the state of the art on this?
A UIScrollView is not so specialized and structured as a UITableView. The former is a generic view that scrolls and zooms anything you put in it, and you can put any subviews into it anywhere, whereas the latter is made especially to display lists of cells stacked on top of each other.
So the answer is: you need to animate the subviews in the scrollview yourself. There are various libraries like Three20 which provide frameworks for creating more advanced views, you'll need to use a suitable component from one of those or roll your own.
Related
Apologies if this has been asked before. I can't find any reference to this particular problem though.
I have an app which is basically a table view nested within a navigation controller. Each item from the table segues to a fresh view (via a generic push transition), containing some content within a scrollview. I have set this all up using storyboard for ease of layout.
When you click an item in the table, the intention is for the table to slide off the screen to the left and be replaced by the content view. This works fine in iOS 6, but since testing the app on iOS 7 I've noticed the functionality is different.
In iOS 7 the content view slides into frame as normal, but the table view only slides a little way to the left - still visible behind my new content. It disappears very suddenly after half a second or so, but the effect is very jarring as it creates a momentary overlap of two views.
This is only a problem because my content views have transparent backgrounds, but this is important to maintain for the effect I want. So just to be clear, my content view slides in over the top of the menu, which subsequently disappears. Looks very odd.
Any help on this would be much appreciated. I'd be curious to know the reason for this change and if there's a way I can fix it. Preferably by making the menu slide all the way offscreen again.
Thanks!
I had the same problem.
Try to add into target ViewController (that shows up after push)
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.backgroundColor = [UIColor redColor];
}
If all is ok you can change background to something like that
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"GreenBkg.png"]];
ps. tableView needs to be defined as #property in your .h filw
I've been struggling with this issue for days, so I hope someone can help me out...
I have a grouped UITableView with several cells. I want to draw some custom graphics above the UITableView that would scroll with the content of the table. Specifically, I want to draw a line with dots, joining the UITableViewCells (across the sections) like this:
Of course if we have more cells than what the screen is capable of displaying, the upper layer with the custom drawing should move with the underlaying cells.
I've tried to subclass UITableView and override it's -drawRect method, but it didn't work. Even if I wouldn't call [super drawRect:rect], the table content displayed without problem.
I've tried to add a new subview to the UITableView, but it changes it's size dynamically when it gets the cells and sections from its datasource... I'm out of ideas...
Although the Web is full of custom UITableViewCell samples, I haven't managed to find anything similiar to my concept...
Can anyone help me how to achieve the above mentioned feature?
First your should subclass UITableView. Then create another UIView and add it as a subView of your custom UITableVIew.
Next override the contentOffset property of the UITableView.
-(void)setContentOffset:(CGPoint)contentOffset
{
[super setContentOffset:contentOffset];
// Custom code here. Update custom subview here.
}
This method will be called as the UITableView is scrolled. You can then adjust the offset of your subview and update its drawing.
I'm trying to write my first iPhone app, and I'm running into a sort of design struggle. What I want to do is have a grid of icons and when you touch one, all the icons above and to the left will "activate" and all the ones below and to the right will "deactivate." If an icon is activated it shows one picture, and if it's not activated it shows another.
The problem I have is that I want to assign a gesture recognizer to each one of these individual icons, and when that icon is tapped, it needs to call a function that updates my grid of icons. But in order to properly update, the function needs to pass as arguments the location of the image in the grid and there's no way to call a function with arguments as part of a gesture recognizer.
So really all I need to do is extend UIImageView to hold two extra integers and the grid it's contained in, and then I could have the following code:
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc] initWithTarget:
self action:#selector(handleTap)];
[imageView addGestureRecognizer:tapgr];
:
:
- (void)handleTap
{
[self.grid updateTableFromRow:self.row andCol:self.col
}
So I suppose this is one way of doing it, but I'm told that I'm not supposed to extend classes in Objective-C, that I should build them from the ground up. In this case, I would just make a custom view with all the properties and/or instance variables I need and I would just fill this custom view with the UIImageView.
This is mostly fine, except when it comes to building my Storyboard. I put all the code that manages and creates this table of icons (programmatically) in another custom view, GridOfIconsView. So on the Storyboard I drag out a custom view and set to be a GridOfIconsView, but then I just see a big white rectangle, and I really want to be able to visualize my app in Storyboard. I know that I can drag out actual image files that I use for the icons onto Storyboard and set them to be a custom view, but then how does that work? Is that image just a background to the custom view? Would I be able to change it programmatically? So if the activated image was a green square, but the deactivated was a red one and I initially dragged out red squares to the Storyboard, would I have access to that red square image?
And a more concerning issue is that I want to manage all these icons in a data structure, either as a 2d array (id icons[][]) or a NS(Mutable?)Array of NS(Mutable?)Arrays. Either way, how could I initialize the data structure to contain links to all these? The grid will be probably 8x8 or 10x10, and there's no way I'm going to have 64-100 #propertys connecting these icons. I'm thinking the only way to sensible organize this is programmatically, but then still, how can I visualize it in Storyboard?
First, it's completely fine to extend classes in Objective-C, and it's done all the time. UIView, UIViewController, UIComponent, etc., were all designed specifically to be subclassed and extended.
However, there are two ways you can do this that are much simpler than extending the class. First, you can have your grid as you already do, where each view has a gesture recognizer attached that calls back to a method on the view controller. Then, you can set a tag on each view (or even just use the view's frame for identification), and read that from the callback method (the gesture recognizer is passed back to the callback method). For example, let's say you had a grid of 4x4 views and you simply numbered them starting in the top-left, advancing each column to the right and then each row, from 0 to 11, you could easily identify the view as such:
// The system automatically passes the gesture recognizer as the only parameter
- (void)handleTap:(UIGestureRecognizer)gestureRecognizer
{
NSInteger viewNumber = [[gestureRecognizer view] tag];
// do something with this view
}
The other way you can do it is to have a single gesture recognizer on the parent view, and then in your -handleTap: callback, you'd query the position of the tap in the view. If the position is within the frame of any of your views, you'd know which one and what to do with it. If not, you could ignore it. This solution requires slightly more math, but also requires far less maintenance and far fewer gesture recognizer that need to be wired up. I would recommend this solution over tagging your views.
I wanna create an app that will have three view controllers. To navigate between them I wanna use swipes and page control (UIPageControl). Also i wanna do this using Stroryboards as much as possible.
What's the best way to implement this?
Thanks
This could also be achieved using the storyboard and segues.
The basic idea is you would create the segues between the 3 UIViewControllers, then capture the swipe gestures, and then call the perform segue to move between views.
On each view, you will have one or two segues:
[ View 1 ] -> gotoView2
gotoView1 <- [ View 2 ] -> gotoView3
gotoView2 <- [ View 3 ]
Here is a video of how to do it.
http://www.youtube.com/watch?v=5u1-DGiUhXU
This is actually quite simple to implement if you know what you need to do. UIPageControl does not help you to achieve paging, it merely displays the dots like on springboard to show what page you are on.
As far as I am aware storyboards let you switch between views or controllers, which if a paging effect is what you are after is not going one much use to you. Your best bet would be to use one view controller and a scrollview on its view.
If you set
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f);
Or something to that effect (you can change the content size to whatever size you want your pages to be. Your scroll view will then snap to those boundaries when scrolling.
If you want to display the current page with a UIPageControl you will need to also add one to your view controller's view. Then implement the UIScollViewDelegate protocol and the method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControl.currentPage = (calculate current page here);
}
In order to make you pages, simply add subviews to the scroll view and it will page between them depending on your set content size.
Hope this help, if it seems unclear or you need any more help, let me know :)
Imagine, there is a UIViewController with a UIScrollView in it. At the top of the view there is an UIImageView, some UILabels and other things. Furthermore, there is a UITableView which content is Dynamic Prototypes. I attach a picture to make it clear:
I haven't got a static amount of cells in the UITableView so it could be scrollable. My problem is the following: the UITableView scrolls in itself but I want to scroll the whole View. What is the best possibility to do that?
Possible solutions I've founded today
1) The first thing is: I create a UITableViewController and declare a header section in which I include all my labels, images etc. programmatically (I would love to use the interface builder for that...)
2) Another solution is to calculate the height of the view. I tried the best to do it like this way - but: without success. If this is the best way to do that: Can anybody give an example?
I would ditch the UIScrollView and just use a UITableView. You can add a UIView object as the tableHeaderView of the UITableView just by dragging it in in Interface Builder. Now since everything is part of the UITableView hierarchy, everything will scroll together as expected.
You could also try setting delaysContentTouches to NO on your scrollView. Depending on your setup, this may make the scroll view respond to the touch first instead of the table view.
From Apples UIScrollView Docs:
delaysContentTouches
A Boolean value that determines whether the scroll view delays the
handling of touch-down gestures.
#property(nonatomic) BOOL delaysContentTouches
Discussion
If the value of this property is YES, the scroll view delays handling
the touch-down gesture until it can determine if scrolling is the
intent. If the value is NO , the scroll view immediately calls
touchesShouldBegin:withEvent:inContentView:. The default
value is YES.
You'll have to (as you've mentioned) add the UIView containing the image and buttons to the actual UITableView. Embedding it in the scroll view will produce the undesired behavior that you're seeing.
I would recommend returning the UIView as the header view for the first section of your table view. You can do this by implementing the UITableViewDelegate method:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
If you maintain an IBOutlet to the view containing your image/labels, you can return it here.
this is same demo i hope its helps you from iphone sorce code library
http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
thank you