Quite new to Xcode UI, I'm trying to use the nice & small pod DRPaginatedScrollView.
This pod allows to scroll between multiple views.
Here is what I did
Added a View Controller to my storyboard
Created a UIViewController subclass
Pointed my View Controller to the class
Here is the content of my class:
#implementation MyViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBoNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBoNil];
if (self) {
self.paginatedScrollView = [DRPaginatedScrollView new];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setup];
[self setupView];
}
- (void)setup {
NSLog(#"Setup");
[self.paginatedScrollView addPageWithHandler:^(UIView *pageView) {
NSLog(#"Handler");
UIView * square = [UIView new];
[square setBackgroundColor:[UIColor redColor]];
[square setFrame:CGRectMake(0, 0, 100, 100)];
[pageView addSubview:square];
}];
}
- (void)setupView {
[self.view insertSubview:self.paginatedScrollView atIndex:0];
NSLog(#"Nb pages: [%ld]", (long)[self.paginatedScrollView numberOfPages]);
}
#end
My log shows only
2014-06-17 12:10:14.113 my_proj[6018:60b] Setup
2014-06-17 12:10:14.115 my_proj[6018:60b] Number of pages: [0]
My main view remains blank, "Handler" is not logged, DRPaginatedScrollView is counting 0 page.
Am I forgetting something ?
I just realized initWithNibName was never called (I don't understand why), so I initialized paginatedScrollView from viewDidLoad, now it's well initialized but still no render.
I did not set DRPaginatedScrollView's frame size:
CGRect frameRect = self.paginatedScrollView.frame;
frameRect.size.width = self.view.frame.size.width;
frameRect.size.height = self.view.frame.size.height;
self.paginatedScrollView.frame = frameRect;
Related
(Let me first put the error up here so that I don't forget it: could not dequeue a view of kind: UICollectionElementKindCell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard)
I've got a regular UICollectionViewController that loads just fine. But I also have another controller (UserViewController) that loads a CollectionView delegate (UserPlaceViewController).
I get really confused with what I have to load in the delegate and what I have to load in the current controller. But anyway here's the delegate as-is:
#import "UserPlaceViewController.h"
#interface UserPlaceViewController ()
#end
#implementation UserPlaceViewController
#synthesize placeArray, placeTable;
- (void)viewDidLoad
{
[super viewDidLoad];
// placeTable.delegate = self;
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
placeTable = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
//self.collectionView.frame = CGRectMake(10, 120, self.view.bounds.size.width-20, self.view.bounds.size.height-50);
placeTable.autoresizesSubviews = YES;
placeTable.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
//placeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
placeTable.scrollEnabled = YES;
self.view = placeTable;
NSLog(#"%lu", (unsigned long)[placeArray count]);
}
That's basically the whole thing. Couple other things at the end... but that's it for the most part.
And here are the relevent parts of the ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:YES];
UserPlaceViewController *collectionView = [[UserPlaceViewController alloc] initWithNibName:#"UserPlace" bundle:nil];
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
[collectionView.placeTable registerNib:placeCell forCellWithReuseIdentifier:cellIdentifier];
- (void) fetchedData: (NSData *) responseData
{
UserPlaceViewController * uptvLike = [[UserPlaceViewController alloc] init];
if (IS_IPHONE5) {
uptvLike.view.frame = CGRectMake(0, 0, 320, 300);
}
else
{
uptvLike.view.frame = CGRectMake(0, 0, 320, 200);
}
uptvLike.placeTable.delegate = self;
uptvLike.placeTable.dataSource = self;
uptvLike.placeTable.layer.borderWidth = 1.0f;
uptvLike.placeTable.layer.borderColor = [UIColor colorWithRed:5/255.0f green:96/255.0f blue:255/255.0f alpha:1.0f].CGColor;
[uptvLike.placeTable reloadData];
[self.scrollView addSubview:uptvLike.view];
}
And finally:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PlaceCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
Place * p = [placeArray objectAtIndex:indexPath.item];
cell.placeName.text = p.PName;
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
return cell;
}
Like I said: I know how a UICollectionView is supposed to work. I've got one running. I know you have to register a nib or class in viewDidLoad (I've registered a Nib.) But I'm confused over how exactly to load this delegate and where to load what. For example I see that I'm initialising the collectionview in both the delegate and the view controller. I'm also confused about WHERE exactly I should load the nib... (delegates give me a headache...)
So what the hell... It's raining. I figured I'd ask.
Ok. You want a UICollectionView but you also want to have a lot of regular "View" items on the same screen? Two things are important:
1. You don't need two ViewControllers. You just need to load what would normally be your UICollectionViewController as a regular ViewController:
#interface UserViewController : UIViewController <UICollectionViewDataSource, UIScrollViewDelegate>
2. Once that's done you can load your collectionview on TOP of that view:
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.scrollView addSubview:self.collectionView];
[self.view addSubview:HUD];
UINib * placeCell = [UINib nibWithNibName:#"UserCell" bundle:nil];
[self.collectionView registerNib:placeCell forCellWithReuseIdentifier:#"Cell"];
The rest is just your standard CollectionView stuff.
Here is the screen of my nib file and map view but the map is always taking the whole view.I tried resetting my simulator and cleaning my Xcode but nothing works.Am i doing something wrong?
Do i need to give mapview a frame programmatically?
http://prntscr.com/1sy1bw
I also want the button to be on top of mapview if the map cannot be set to take a particular frame.
Consider the below code please:
#import "mapViewController.h"
#interface mapViewController ()
#end
#implementation mapViewController
#synthesize mapView,source,dest,latdest,latsource,longdest,longsource;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
dest=#"delhi";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,0,160,240)];
CLGeocoder *geocoder1 = [[CLGeocoder alloc] init];
[geocoder1 geocodeAddressString:source
completionHandler:^(NSArray* placemarks, NSError* error)
{
for (CLPlacemark* aPlacemark in placemarks)
{
coordinate.latitude = aPlacemark.location.coordinate.latitude;
latsource=&coordinate.latitude;
coordinate.longitude = aPlacemark.location.coordinate.longitude;
longsource=&coordinate.longitude;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:(coordinate)];
[annotation setTitle:source];
annotation.subtitle = #"I'm here!!!";
mapView.delegate = self;
[self.mapView addAnnotation:annotation];
}
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
//mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0,0,160,240)];
CLGeocoder *geocoder1 = [[CLGeocoder alloc] init];
[geocoder1 geocodeAddressString:source
completionHandler:^(NSArray* placemarks, NSError* error)
{
for (CLPlacemark* aPlacemark in placemarks)
{
coordinate.latitude = aPlacemark.location.coordinate.latitude;
latsource=&coordinate.latitude;
coordinate.longitude = aPlacemark.location.coordinate.longitude;
longsource=&coordinate.longitude;
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
[annotation setCoordinate:(coordinate)];
[annotation setTitle:source];
annotation.subtitle = #"I'm here!!!";
[self.view addSubview:mapView];
[self.mapView addAnnotation:annotation];
}
}];
}
I commented the mapview alloc codeline and this fixed the issue.Seems like mapview gets pushed as soon as its allocated memory space.Moreover the frame coordinated that i initialised mapviewview with are still preserved although the code is commented.Dont know if it should work this way only or not but it did solved my issue .
I want to show images in a grid on iPhone using a UICollectionView, showing 3 images a row. For a "dead simple test" (as I thought), I've added 15 JPG images to my project, so that they'll be in my bundle and I can load them simply via [UIImage imageNamed:...].
I think I've done everything correct (setting up & registering UICollectionViewCell subclass, use of UICollectionViewDataSource Protocol methods), however, the UICollectionView behaves very weird:
It shows only a few of the images in the following pattern:
First line shows image 1 & 3, second line is blank, next line like the first again (image 1 & 3 showing properly), fourth line blank, and so on...
If I push a button in my NavBar that triggers [self.collectionView reloadData], random cells appear or disappear. What drives me nuts is that it's not only an issue of images appear or not. Sometime, images also swap between the cells, i.e. they appear for a indexPath they are definitely not wired up!
Here is my code for the cell:
#interface AlbumCoverCell : UICollectionViewCell
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#end
#implementation AlbumCoverCell
#synthesize imageView = _imageView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_imageView = [[UIImageView alloc] initWithFrame:frame];
[self.contentView addSubview:_imageView];
}
return self;
}
- (void)dealloc
{
[_imageView release];
[super dealloc];
}
- (void)prepareForReuse
{
[super prepareForReuse];
self.imageView.image = nil;
}
#end
Part of the code for my UICollectionViewController subclass, where 'imageNames' is an NSArray holding all jpg filenames:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[AlbumCoverCell class] forCellWithReuseIdentifier:kAlbumCellID];
}
#pragma mark - UICollectionViewDataSource Protocol methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.imageNames count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
AlbumCoverCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kAlbumCellID forIndexPath:indexPath];
NSString *imageName = [self.imageNames objectAtIndex:indexPath.row];
NSLog(#"CV setting image for row %d from file in bundle with name '%#'", indexPath.row, imageName);
cell.imageView.image = [UIImage imageNamed:imageName];
return cell;
}
#pragma mark - UICollectionViewDelegateFlowLayout Protocol methods
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
{
return CGSizeMake(100, 100);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
From the NSLog statement in cellForItemAtIndexPath: I can see that the method is called for all of the cells (not only the one's displayed) and that the mapping between indexPath.row and filename is correct.
Has anybody an idea what could cause this weird behavior?
In the meantime, I've found the solution. It was actually a very subtle error in the implementation of my UICollectionViewCell subclass AlbumCoverCell.
The problem is that I've set the frame of the cell instance as the frame of the UIImageView subview instead of passing the bounds property of the cell's contentView!
Here is the fix:
#implementation AlbumCoverCell
#synthesize imageView = _imageView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// WRONG:
// _imageView = [[UIImageView alloc] initWithFrame:frame];
// RIGHT:
_imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds];
[self.contentView addSubview:_imageView];
}
return self;
}
- (void)prepareForReuse
{
[super prepareForReuse];
// reset image property of imageView for reuse
self.imageView.image = nil;
// update frame position of subviews
self.imageView.frame = self.contentView.bounds;
}
...
#end
I am making an iPhone and iPod app that I will make in portrait mode only. There comes a point in the app where if the user touches a picture, it will make itself fullscreen. The way I do that is via a segue to another view controller, where a UIImageView takes the whole space. I would like to be able to rotate the device in landscape to view the picture in landscape.
How it that possible?
In a second phase: I would like to know how to make the view fullscreen, so the picture could fill the entire screen.
Basically: I want the picture to behave just like the twitter app. :)
Thanks
EDIT: here is the code in my Class to view the image
#import "ImageViewer.h"
#interface ImageViewer ()
#end
#implementation ImageViewer
#synthesize scrollView;
#synthesize imageView;
#synthesize image;
- (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.
CGRect imageFrame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
self.imageView.frame = imageFrame;
self.scrollView.contentSize = imageFrame.size;
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)sender
{
return self.imageView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
NSLog(#"rotate.");
return YES;
}
- (void)viewDidUnload {
[self setImageView:nil];
[self setScrollView:nil];
[super viewDidUnload];
}
#end
I am confused about why this code does not display any image:
In the app delegate:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSRect rect = window.frame;
rect.origin.x = 0;
rect.origin.y = 0;
BlueImageView *blueImageView = [[BlueImageView alloc]initWithFrame:rect];
window.contentView = blueImageView; // also tried [window.contentView addSubview: blueImageView];
}
BlueImageView.h:
#interface BlueImageView : NSImageView {
}
#end
BlueImageView.m:
#implementation BlueImageView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setImage: [NSImage imageNamed:#"imagefile.png"]];
NSAssert(self.image, #"");
NSLog (#"Initialized");
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect {
}
#end
The file imagefile.png exists. The NSAssert is not causing an exception. The NSLog is firing. But no image shows up in the window.
The drawRect: method is called to draw the view, and your implementation immediately returns. To get NSImageView to draw the image for you, call [super drawRect:dirtyRect]; in your implementation of drawRect:. If you aren't going to do any other drawing in drawRect:, just remove the method to speed up drawing.