The Horizontal Scroll will work fine, but UIpagecontroller will not work means it will not change, As I scroll the page. I can't able to identify the error. Please see below code
#import "ViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIScrollView *scroll;
#property (strong, nonatomic) IBOutlet UIPageControl *pgcnt;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *arry=[NSArray arrayWithObjects:#"a",#"b",#"c",#"e",#"f", nil];
for (int i=0; i<arry.count; i++) {
CGRect frame;
[self.scroll setPagingEnabled:YES];
_scroll.pagingEnabled=YES;
_scroll.bounces = YES;
[_scroll setShowsHorizontalScrollIndicator:NO];
[_scroll setShowsVerticalScrollIndicator:NO];
frame.origin.x=_scroll.frame.size.width*i;
frame.size=_scroll.frame.size;
UIView *view=[[UIView alloc]initWithFrame:frame];
view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:[arry objectAtIndex:i]]];
[_scroll addSubview:view];
[self.pgcnt setCurrentPage:i];
// self.pgcnt.numberOfPages=arry.count;
}
_scroll.contentSize=CGSizeMake(_scroll.frame.size.width*arry.count,_scroll.frame.size.height);
// Do any additional setup after loading the view, typically from a nib.
}
Any suggestion or help will appreciated
I found the solution , no one helped me, but its ok, i will help other people .i Didn't added delegate method thats why the Pagecontrol dot will not worked. But now working fine.
pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scroll.frame.size.width;
int page = floor((self.scroll.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pgcnt.currentPage = page;
}
thanks for
http://iosmadesimple.blogspot.in/2013/01/page-control-for-switching-between-views.html
Related
I have an iPhone application in which i need to load a bulk of images (ie around 50),which has a small rect like (little above thumbnail) containing 3 in each row with 4 columns in one page, and i need to scroll horizontally to load the next 12 images and so on. Also i need to show the page number under it as 1,2 etc.
Can any body guide me in the right direction to achieve this in a scroll view ?i am really in a mess ,how to add imageview to a scrollview like this ,also each image view has its own buttons also.
The way i would tackle this problem goes as follows: (I am not going to provide many details as they are dependent on your particular needs and requirements).
.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>
#property (unsafe_unretained, nonatomic) IBOutlet UIScrollView *scrollView;//assuming the scrollView is connected in a xib file
-(id)initWithImages:(NSArray*)images;//that could be whatever format you get your images(UIImage, urls to download, file names or custom views. Here we assume that the array contains instances of UIImage)
#end
.m file:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSArray *images;
#property (nonatomic, assign) CGFloat pageWidth;
#property (nonatomic, assign) int currentPage;
#end
#implementation ViewController
-(id)initWithImages:(NSArray*)images{
self = [super init];
if(self){
self.images = images;
}
return self;
}
-(void)viewDidLoad{
[super viewDidLoad];
[self.scrollView setDelegate:self];
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width*self.imageURLsArray.count,
self.scrollView.frame.size.height)];
[self.scrollView setPagingEnabled:YES];
[self.scrollView setShowsVerticalScrollIndicator:NO];
self.pageWidth = self.scrollView.frame.size.width;
for(int i = 0; i < self.images.count; i++){
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.scrollView.frame.size.width*i,
self.scrollView.frame.origin.y,
self.scrollView.frame.size.width,
self.scrollView.frame.size.height)];
imageView.image = [self.images objectAtIndex:i];
[self.scrollView addSubview:imageView];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
int page = floor(scrollView.contentOffset.x - self.pageWidth/2)/self.pageWidth + 1;
if(self.currentPage != page){
NSLog(#"Scrolled to new page: %d", page);
self.currentPage = page;
//do additional things based on the fact that you have scrolled to a new page (like changing the page number)
}
}
#end
Use UItableview create custom cell with two imageviews on it and load that custom cell to cell for indexpath then create an nsarray and pass the image names into that array and then convert that image into data format for eg
nsdata *data = [NSdata dataWithcontents of url [array object at index:indexpath.row]];
cell.imageview.image = [uiimage imagewithdata:data];
for this you should know to create custom cells.
I can't quite figure out what's going on but I have a view that displays a subview when a users selects a button. This subview then also has a button the user can select to cancel and remove this subview. When all of this happens, my app crashes when you attempt to close the subview.
This is my code:
From the main view that shows the subview when a button is selected -
-(IBAction)sendMessage:(id)sender{
NSLog(#"Going to send a message....");
CGRect frameBounds = [self.view bounds];
float frameWidth = frameBounds.size.width;
float frameHeight = frameBounds.size.height;
float frameX = frameBounds.origin.x;
//float frameY = frameBounds.size.height / 2;
float frameY = frameBounds.size.height;
float finalY = frameBounds.size.height / 1.75;
MessageChooserController *chooser = [[MessageChooserController alloc] initWithNibName:#"MessageChooser" bundle:nil];
//Set the frame off the screen at the bottom
chooser.view.frame = CGRectMake(frameX, frameY, frameWidth, frameHeight);
[self.view addSubview:chooser.view];
[UIView animateWithDuration:0.5 animations:^{chooser.view.frame = CGRectMake(frameX, finalY, frameWidth, frameHeight);}];
}
As you can see this simply shows a new subview - MessageChooserController. Now this subview, MessageChooserController has a button to cancel this "action".
The header file for MessageChooserController:
#import <UIKit/UIKit.h>
#interface MessageChooserController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *btn_sendEmail;
#property (weak, nonatomic) IBOutlet UIButton *btn_sendText;
#property (weak, nonatomic) IBOutlet UIButton *btn_cancel;
-(IBAction)closeChooser:(id)sender;
#end
And its implementation:
#import "MessageChooserController.h"
#interface MessageChooserController ()
#end
#implementation MessageChooserController
#synthesize btn_cancel, btn_sendEmail, btn_sendText;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
/*
[btn_cancel setBackgroundImage:[[UIImage imageNamed:#"iphone_delete_button.png"] stretchableImageWithLeftCapWidth:8.0f topCapHeight:0.0f] forState:UIControlStateNormal];
*/
/*
UIImage *cancelButtonImage = [[UIImage imageNamed:#"iphone_delete_button"] resizableImageWithCapInsets:UIEdgeInsetsMake(30,0,30,0)resizingMode:UIImageResizingModeStretch];
[btn_cancel setBackgroundImage:cancelButtonImage forState:UIControlStateNormal];
*/
}
-(IBAction)closeChooser:(id)sender{
[self.view removeFromSuperview];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
As you can see I have a simple method to close this subview, closeChooser. All of this compiles but when I select the cancel button on the subview my app crashes. I can't find anything anywhere about this.
Essentially I want to have a view display like it does when you select "Send message" from your contacts.
The correct way of doing this is calling [self presentModalViewController:viewController] on the parent view controller and then calling [self dismissModalViewController] when you want to hide it.
I'm trying to add UIScrollView with paging as a header to my table, but unfortunately it is not displayed correctly.
The htableHaderView is resized to the size of my imagesScrollView, but only half of it is displayed the rest area is blank.
- (void)viewDidLoad
{
[super viewDidLoad];
ImagesViewController *imagesScrollView = [[ImagesViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
tableView.tableHeaderView = imagesScrollView.view;
imagesScrollView = nil;
}
Thanks for helping
I tried the following code:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController
#end
ViewController.m
#import "ViewController.h"
#import "ImagesViewController.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ImagesViewController *imageVC = [[ImagesViewController alloc] initWithNibName:#"ImagesViewController" bundle:nil];
[[self tableView] setTableHeaderView:[imageVC view]];
imageVC = nil;
}
#end
ImagesViewController.h
#import <UIKit/UIKit.h>
#interface ImagesViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIScrollView *ScrollView;
#property (strong, nonatomic) IBOutlet UIView *ViewInScrollView;
#end
ImagesViewController.m
#import "ImagesViewController.h"
#implementation ImagesViewController
#synthesize ScrollView;
#synthesize ViewInScrollView;
- (void)viewDidLoad {
[super viewDidLoad];
[[self ViewInScrollView] setFrame:CGRectMake(0, 0, 768 * 2, 400)];
[[self ViewInScrollView] setBackgroundColor:[UIColor orangeColor]];
[[self ScrollView] setContentSize:[[self ViewInScrollView] frame].size];
}
#end
ImagesViewController's xib is a view, 768 wide by 200 tall (I made an iPad-based UITableView single-view application). Inside its view is a UIScrollView, set to take up the entire [view frame] area. Then I put a UIView inside of it.
My testing gives me a header that is an orange rectangle, and I can scroll it around as you would expect. This leads me to believe that maybe you need to check the shocks/struts of your imagesScrollView in Interface Builder. Make sure all of the margins and widths are fixed/flexible as you need for it to display properly.
I'm trying to create a CGRect inside of a custom view (rectView) that will move up and down as you move a slider.
My slider's IBAction calls the following method: (which get's called fine)
- (void)moveRectUpOrDown:(int)y
{
self.verticalPositionOfRect += y;
[self setNeedsDisplay];
}
My drawRect method:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat size = 100;
self.rect = CGRectMake((self.bounds.size.width / 2) - (size / 2),
self.verticalPositionOfRect - (size / 2),
size,
size);
CGContextAddRect(context, self.rect);
CGContextFillPath(context);
}
My custom view's initWithFrame calls the drawRect method using setNeedsDisplay, but for some reason the moveRectUpOrDown won't call drawRect.
Any ideas what I'm doing wrong?
For clarity the entire implementation is below:
//ViewController.h
#import <UIKit/UIKit.h>
#import "rectView.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet rectView *rectView;
- (IBAction)sliderChanged:(id)sender;
#end
//ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize rectView;
- (void)viewDidLoad
{
[super viewDidLoad];
self.rectView = [[rectView alloc] initWithFrame:self.rectView.frame];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)sliderChanged:(id)sender
{
UISlider *slider = sender;
CGFloat sliderValue = slider.value;
[self.rectView moveRectUpOrDown:sliderValue];
}
#end
//rectView.h
#import <UIKit/UIKit.h>
#interface rectView : UIView
- (void)moveRectUpOrDown:(int)y;
#end
//rectView.m
#import "rectView.h"
#interface rectView ()
#property CGRect rect;
#property int verticalPositionOfRect;
#end
#implementation rectView
#synthesize rect, verticalPositionOfRect;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.verticalPositionOfRect = (self.bounds.size.height / 2);
[self setNeedsDisplay];
}
return self;
}
- (void)moveRectUpOrDown:(int)y
{
self.verticalPositionOfRect += y;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat size = 100.0;
self.rect = CGRectMake((self.bounds.size.width / 2) - (size / 2),
self.verticalPositionOfRect - (size / 2),
size,
size);
CGContextAddRect(context, self.rect);
CGContextFillPath(context);
}
#end
Thanks for the help :)
OK so the answer is the view is never actually added to the viewController's view..
You have an IBOutlet to your rectView - so I assume you dragged a UIView component onto the view in Interface Builder and then changed it's class to rectView, which is all fine BUT in viewDidLoad you wipe over this object with a new one
self.rectView = [[rectView alloc] initWithFrame:self.rectView.frame];
So this is now no longer the object that was loaded from the xib.
Subsequently this view is never actually added to the view hierarchy so it's never going to draw itself as it does not make sense.
So the solution is to remove the line I highlighted above.
Notes
I would probably still go with my other answer for such an implementation but it's helpful to get tripped up and learn new things.
rectView does not follow naming conventions. Ideally you should start your class name with a 2-3 letter prefix (possibly your initial's or company name) followed by a camel cased named.
I don't see how you initialize CGFloat size. Can you put a value in there and see how it works? The rest of the code looks okay to me.
An easier thing would be to just add a UIView and animate this around.
Add an ivar for this UIView
// .h
#property (nonatomic, strong) UIView *animatedView;
// .m
#synthesize animatedView = _animatedView;
then just replace your logic with this
- (void)moveRectUpOrDown:(int)y;
{
CGRect frame = self.animatedView.frame;
frame.origin.y += y;
// If you want the change to animate uncomment this
// [UIView animateWithDuration:0.25f
// animations:^{
// self.animatedView.frame = frame;
// }];
// If you don't want the change to animate uncomment this
// self.animatedView.frame = frame;
}
I've been trying to solve this bad reference for 2 days now, but I cannot find a fix.
My application is a basic to-do list with several pages (UIPageControl) for different categories and a first page for statistics about the tasks the user has finished. (if you got 3 categories, you end up with 4 pages).
It loads an array of categories from NSUserDefaults, which can be modified by a modal view accessed through a UIButton just like the (i) in the wheather app.
The Page Control is built by the ViewController class, (which is the primary view). For each element in the array of categories, the view controller generates a new TasksPageViewController class instance and instantiates a storyboard view for it.
Everything was working fine untill I put a UITableView in the TasksPageViewController view in storyboard and linked its dataSource to the same class.
After implementing the required classes for the UITableView dataSource in the TasksPageViewController, it runs fine, but if I try to go to the modal view for modifying the categories, when I press DONE (and it should reload the ViewController and rebuild the many pages for the UIPageControll), the application crashes with a EXEC_BAD_ACCESS.
Debugging with NSZombiesEnabled, I got:
2012-02-12 18:55:49.460 Pontinhos[25601:fe03] *
-[TasksPageViewController tableView:numberOfRowsInSection:]: message sent to deallocated instance 0x68c3040
But I don't really know how to proceed, I don't know which object that have been released I'm calling.
The scripts are the following:
ViewController.h
#import <UIKit/UIKit.h>
#import "MainPageViewController.h"
#import "TasksPageViewController.h"
#interface ViewController : UIViewController{
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
NSMutableArray * views;
// To be used when scrolls originate from the UIPageControl
BOOL pageControlUsed;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#property (nonatomic, retain) IBOutlet UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *views;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (IBAction)changePage;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize scrollView;
#synthesize pageControl;
#synthesize views;
//carrega views que estão na array.
- (void)viewDidLoad
{
[super viewDidLoad];
//LoadCategories
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
NSMutableArray *categories = [[NSMutableArray alloc] initWithArray:[data objectForKey:#"categories"]];
// MAIN PAGE
MainPageViewController *mainpage = [self.storyboard instantiateViewControllerWithIdentifier:#"MainPageViewController"];
CGRect mframe = scrollView.frame;
mframe.origin.x = 0;
mframe.origin.y = 0;
mainpage.view.frame = mframe;
[self.scrollView addSubview:mainpage.view];
int i = 1;
NSLog(#"Iniciando criação de páginas!");
for(id name in categories) {
NSLog(#"Carregou página.%i",i);
NSLog(#"categories count:%i",[categories count]);
TasksPageViewController *tasks = [self.storyboard instantiateViewControllerWithIdentifier:#"TasksPageViewController"];
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * i;
frame.origin.y = 0;
tasks.view.frame = frame;
[tasks populateWithData:(i-1) categoryName:name];
[scrollView addSubview:tasks.view];
tasks = nil;
i++;
}
self.pageControl.numberOfPages = [categories count]+1;
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * ([categories count]+1), self.scrollView.frame.size.height);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (pageControlUsed)
{
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Update the page when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
- (IBAction)changePage {
// update the scroll view to the appropriate page
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
pageControlUsed = YES;
}
// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.scrollView = nil;
}
#end
TasksPageViewController.h
#import <UIKit/UIKit.h>
#import "TasksTableCellPrototypes.h"
#interface TasksPageViewController : UIViewController <UITableViewDataSource>{
IBOutlet UILabel *categoryName;
IBOutlet UITableView *tableView;
//NSMutableArray *tasksData;
}
//#property (nonatomic,retain) NSMutableArray *tasksData;
#property (nonatomic,retain) UITableView *tableView;
#property (nonatomic,retain) UILabel *categoryName;
- (void) populateWithData:(int)dataId categoryName:(NSString *)name;
#end
TasksPageViewController.m
#import "TasksPageViewController.h"
#implementation TasksPageViewController
#synthesize tableView;
//#synthesize tasksData;
#synthesize categoryName;
- (void)viewDidLoad
{
[super viewDidLoad];
// NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
//tasksData = [[NSMutableArray alloc] initWithArray:[data objectForKey:#"tasks"]];
//tasksData = [[NSMutableArray alloc] initWithObjects:#"lalal",#"lololo",nil];
}
- (void) populateWithData:(int)dataId categoryName:(NSString *)name {
//self.categoryName.text = name;
}
// Número de categorias
- (NSInteger)tableView:(UITableView *)tableViewnumberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"contou table view tasks");
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TasksTableCellPrototypes *cell = [[TasksTableCellPrototypes alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"taskCell"];
return cell;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
Thank you.
EDIT: apparently The ViewController isn't retaining the reference to the TasksPageViewController and the UITableView cannot find its dataSource. I don't really know how to retain this using ARC.
In your ViewController viewDidLoad, when you loop through the categories you instantiate a TasksPageViewController named tasks, but then you do not retain the reference anywhere. So later the TasksPageViewController cannot be found when the tableView:numberOfRowsInSection: message is sent.
I see that in your ViewController your synthesize a property named views but then you do not use that property anywhere. Perhaps you should rename that property viewControllers and then at the end of the loop in viewDidLoad, you should add your tasks object to the viewControllers mutable array, instead of setting tasks to nil. I think that might prevent the crash.
for(id name in categories) {
TasksPageViewController *tasks = [self.storyboard instantiateViewControllerWithIdentifier:#"TasksPageViewController"];
...
[scrollView addSubview:tasks.view];
[self.viewControllers addObject:tasks];
i++;
}