Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
In a game that I am developing for iPhone, I would like to create a bingo board in which you can click one of the spots, and the camera opens. I have the camera part down, but I'm working on creating the board. I thought a Collection View with 25 items would work for the grid, but nothing is appearing on the screen when the app is running. Is there a better way to go about making the table?
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:NO animated:animated];
[super viewWillDisappear:animated];
}
- (IBAction)cameraButtonClicked:(id)sender {
if (![UIImagePickerController isSourceTypeAvailable:(UIImagePickerControllerSourceTypeCamera)]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Camera Not Available" message:#"The camera feature isn't available on your device." delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alertView show];
}else{
//Show the Image Picker Controller Here
UIImagePickerController * ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
ipc.allowsEditing = NO;
//Set the Delegate
ipc.delegate = self;
[self.navigationController presentViewController:ipc animated:YES completion:nil];
}
}
#pragma mark ImagePicker Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
self.imageView.image = image;
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
I think your bingo board might be better implemented with multiple views or custom drawing. I personally would opt for custom drawing since I'm pretty comfortable there. Regarding your collection view idea, the only reason it may not be the best is because of less control over the inter-item spacing. In my experience, it is difficult to get the items to sit immediately between each other. I'll go down each potential route and give you my 2 cents:
1. Collection View
Do some research on laying out a perfectly aligned grid. You'll probably have to have a custom layout or change the collection view inset and / or minimumInteritemSpacing. See the following SO posts:
how do you determine spacing between cells in UICollectionView flowLayout
ios UICollectionView separation on top / bottom between cells
Cell spacing in UICollectionView
2. Manually-placed views
This technique will work if you know that you will only have a set number of bingo "slots" or "squares". You could create this in code, a storyboard, or a xib.
3. Custom Drawing / Layout
I would advocate for this technique because of its flexibility. You could pass the number of bingo tiles that you need and then either build UIButtons with a flat tile-like appearance or with the button style UIButtonTypeCustom. Another custom drawing way is to draw with CoreGraphics. However, this would not lend itself well to clean actions like from a UIButton and would require that you re-implement touch methods.
Conclusion
I would either try to go with the collection view if you can get the inter-item spacing worked out or I would go with calculated views laid out in code or if you have a fixed number of items then laid out in a storyboard or something.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want images to be displayed dynamically, for ex- if user selects 10 images, all those should get displayed, now if user wants to select 5 more images, so (10+5) 15 images should get displayed. How to achieve this functionality?
I am using UIImagePickerController to select images, so at a time user will be able to select 1 image only.I have given a add photo button.
UIImagePickerController *galleryObj=[[UIImagePickerController alloc]init];
galleryObj.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
galleryObj.allowsEditing = YES;
galleryObj.delegate=self;
[self presentViewController:galleryObj animated:YES completion:nil];
Above will get executed when user taps on add photo button.
//GalleryViewcontroller.h
#import <UIKit/UIKit.h>
#interface GallaryViewController : UIViewController<UIImagePickerControllerDelegate>
{
NSMutableArray *selectedImagesArray;
}
#end
GalleryViewcontroller.m
#implementation GallaryViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//allocating array
selectedImagesArray=[[NSMutableArray alloc]init];
}
-(IBAction)openGallery:(id)sender
{
UIImagePickerController *galleryObj=[[UIImagePickerController alloc]init];
galleryObj.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
galleryObj.allowsEditing = YES;
galleryObj.delegate=self;
[self presentViewController:galleryObj animated:YES completion:nil];
}
#pragma mark UIImagePickerController Delegate
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
//here we are adding the image in array
[selectedImagesArray addObject:[info objectForKey:UIImagePickerControllerOriginalImage]];
NSLog(#"%#",selectedImagesArray);
//reload your colleciton view or tableview or any other view which your using to show selected images
//you can get images by index
//UIImage *img=[selectedImagesArray objectAtIndex:0];
}];
}
#end
i have created a simple app with two buttons and one uiimageview.
One button takes a photo from photo library and puts it on uiimageview.
When the user adds another photo the old one should be saved and then user can swipe between these two photos.
another button takes a photo and put it on uiimageview.
So now i'm really confused about swiping between photos. I read that uiimageview can contain only one image. Also, i read that i need to add uiScrollView to UiImageView, but i don't know how they work together.
should i delete my UIImageView and then create ScrollView instead of it?
Here is my code
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)pickPhoto:(id)sender {
picker1 = [[UIImagePickerController alloc]init];
picker1.delegate = self;
[picker1 setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:picker1 animated:YES completion:NULL];
}
- (IBAction)takePhoto:(id)sender {
picker2 = [[UIImagePickerController alloc]init];
picker2.delegate = self;
if([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]){
}
else{
NSLog(#"not avaialbe");
}
[self presentViewController:picker2 animated:YES completion:NULL];
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
image = [info objectForKey:UIImagePickerControllerOriginalImage];
[self.imageView setImage:image];
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
UPDATE
So i have added a method that allows user to swipe left or right and he can see different pictures, however, i had to hard code my images into the code. But i want to select images from the photo library, then these images will be saved in the array and then if user adds more pictures he has a choice to swipe through his old images.
Here is my code for swiping through the images
- (IBAction)Swipe:(id)sender {
NSArray *images = [[NSArray alloc]initWithObjects:#"ayat.png", #"qwe.png",#"4444", #"15", nil];
UISwipeGestureRecognizerDirection direction = [(UISwipeGestureRecognizer *) sender direction];
switch(direction)
{
case UISwipeGestureRecognizerDirectionLeft:
imageIndex++;
break;
case UISwipeGestureRecognizerDirectionRight:
imageIndex--;
break;
default:
break;
}
imageIndex = (imageIndex <0)?([images count] -1 ):
imageIndex % [images count];
self.imageView.image = [UIImage imageNamed:[images objectAtIndex:imageIndex]];
}
but here i added pictures to my project.
It's true that a UIImageView can display only a single image.
There are various ways to handle this. One would be to use a UIPageViewController. That would enable you to set up side-swipe based paging between pages of content. There is a sample app from Apple called PhotoScroller (it used to be linked from the Xcode help system. With Xcode 6, apple seems to have removed all sample code. You'll have to search the net for the sample app. That app also includes tiled rendering, which is likely overkill for your application, but it does show how to set up a page view controller.
You could also use a UICollectionView, or create your own custom view that manages a set of views.
Actually now that I think about it a UICollectionView set up for paging might be your best bet.
In my test app, I have two buttons (takePhoto1 and takePhoto2) and two UIImageViews (photo1View and photo2View). The first button takes a photo and displays it in the first image view. The second button takes another photo, and is supposed to display it in the second image view. However, for some reason second photo is displayed in photoView1 instead of photoView2.
I haven't implemented any code to save the photos yet, so I'm not worried about the photos persisting in the image views.
What I do need to figure out is how to make sure when the second photo is taken, it is displayed in the appropriate view. Here is what I have so far:
//Take photo1 and display in top image view
- (void)takePhoto1;
{
[self dismissViewControllerAnimated:YES completion:NULL];
if ([self.capturedImages count] > 0)
{
if ([self.capturedImages count] == 1)
{
// Camera took a single picture.
[self.photo1View setImage:[self.capturedImages objectAtIndex:0]];
}
// To be ready to start again, clear the captured images array.
[self.capturedImages removeAllObjects];
}
self.imagePickerController = nil;
}
//Take photo2 and display in bottom image view
- (void)takePhoto2;
{
[self dismissViewControllerAnimated:YES completion:NULL];
if ([self.capturedImages count] > 0)
{
if ([self.capturedImages count] == 1)
{
// Camera took a single picture.
[self.photo2View setImage:[self.capturedImages objectAtIndex:1]];
}
// To be ready to start again, clear the captured images array.
[self.capturedImages removeAllObjects];
}
self.imagePickerController = nil;
}
Anyone know how to fix this?
I saw your questions an couldn't help my self to solve it in my way. If I had same problem as yours I would have solved it in this way:
Consider, button's tag is same as, imageView tag.
#import "ViewController.h"
#interface ViewController ()
- (IBAction)takePhoto:(id)sender;
#property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *imageViews;
#property int tag;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)takePhoto:(id)sender {
_tag = ((UIButton *)sender).tag;
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
#pragma mark - UIImagePickerDelegate Methods
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo{
[picker dismissViewControllerAnimated:NO completion:nil];
[[self getImageView:_tag] setImage:image];
}
- (UIImageView *) getImageView : (int) tag{
for (UIImageView *imageView in _imageViews) {
if (imageView.tag == tag) {
return imageView;
}
}
return nil;
}
#end
Here you can check this as working project here.
Check your storyboard or xib to see if "photo2View" is really connected to your outlet.
I suspect the UIImageView for "photo1View" is also connected to "photo2View".
p.s. you should also change this line in your #implementation:
- (void)takePhoto2;
to this:
- (void)takePhoto2
semi-colons should only come after method declarations in your .h file.
Does your code work? I find two issues -
Issue 1 - This should crash as capturedImages has one element according to second if check but you are accessing second element in the array while setting the imageView.
if ([self.capturedImages count] == 1)
{
// Camera took a single picture.
[self.photo2View setImage:[self.capturedImages objectAtIndex:1]];
Issue 2 - Since you are clearing the self.capturedImages, this should have thrown you can exception in second method.
[self.photo2View setImage:[self.capturedImages objectAtIndex:1]];
Did you properly connect button 1 to takePhoto1 and button 2 to takePhoto2? Maybe button 2 is also doing takePhoto1?
I have a scrollViewController, in viewDidLoad, I add an UIImageView to it:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.scrollView addSubview:self.imageView];
}
Then I set my image:
- (void)setImage:(UIImage *)image
{
self.scrollView.zoomScale = 1.0;
self.imageView.image = image;
self.imageView.frame = CGRectMake(0,0,image.size.width,image.size.height);
self.scrollView.contentSize = self.image ? self.image.size : CGSizeZero;
}
On iPhone, this works fine, but on iPad (SplitViewController Detail), it doesn't show anything.
I think the problem is, that on iPhone ViewDidLoad is called when there is already an image set, on iPad when the app launches, the detail is always on screen.
I tried to put the addSubview to setImage, this works, but when the user clicks another item, the two imageViewControllers overlay each other.
Could anyone help me? Thanks! :-)
The basics:
viewDidLoad is only called once the controller is loaded into memory. So in your SplitViewController the viewDidLoad method is invoked immediately after launching the app.
My suggestion:
Add a UIImageView from InterfaceBuilder and connect it to your controller using a IBOutlet. This is the easiest way to reach the goal. I assume you're using a storyboard?!
right click drag the outlet to your header:
enter a name for your property and click connect
This way you can access your UIImageView in your implementation and you're good to go. No need to add it programmatically.
For further informations have a look at this tutorial: http://klanguedoc.hubpages.com/hub/IOS-5-A-Beginners-Guide-to-Storyboard-Connection
Before adding second imageViewController, you should remove first imageViewController
Try this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//_imageView variable is created by outlet, or you can do it by programmatically
_imageView.image = [UIImage imageNamed:#"1"];
}
- (void) setNewImage
{
[_imageView removeFromSuperview];
_imageView.image = [UIImage imageNamed:#"2"];
}
I've been wondering for a few time now how does Xcode interpret the use of both IB and programmaticaly coded objects.
ex : I initWithStyleGrouped a table in .m but I set plain as the style in the attributes of the tableviewcontroller I am working on. so? I noticed that the code gets over the IB.
It first appears when I had to custom a detail table by insering a header and a UITextField in the first cell which is very easy with IB. But when I run the app, nothing but the template of a plain table.
gnuh??
Thank you for your help.
Cheers,
Louis
EDIT
here is the instantiate of the TableViewController :
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
They should never cross. If you instantiate a table with [[UITableView alloc] initWithStyle:UITableViewStyleGrouped], it creates a new table without going though a NIB. If you instantiate a table from a NIB, it creates an instance using -initWithCoder:.
Added after Update
OK, you are subclassing UITableView. In addition to overriding -initWithStyle:, you will want to override -initWithCoder: or -awakeFromNib.
The basic flow of loading an custom UIView from a NIB.
-initWithCoder: is used to instantiate the object
All NIB connections are make (IBOutlets and IBAction are connected).
-awakeFromNib is send to the object
This means if you set a value in -initWithCoder:, the NIB setting will win; if you set a value in -awakeFromNib, the your code will win.
Be sure to read the Subclassing Notes and Methods to Override sections of UIView.
It all depends on how you initialize the object. If you load the UITableView from your controller's init method and call initWithStyle, that's what your UITableView will be. If you want to use IB's, you'll need to initialize your controller with initWithNibName and have an IBOutlet connection to your view, which has the plain setting.
Well, I am not sure but I think I found a beginning of solution. here are my thoughts.
I consider a IB oriented design.
the compiler will ask for IB to instantiate the view.
But if we created a UITableViewController subclass, then we have all the method refering to the instantiation (correct word?) of this view.
So, in order to avoid this conflict, We can erase the code in the .M which refers to the initialization of the table : initWithStyle and the pragma mark about Table source. we just let the View life cycle needed by any view and the delegate.
I found some exemple using this. here is the .m of a detail view table which is designed with static cells on IB :
#import "PictureListDetail.h"
#implementation PictureListDetail
#synthesize managedObjectContext;
#synthesize currentPicture;
#synthesize titleField, descriptionField, imageField;
#synthesize imagePicker;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// If we are editing an existing picture, then put the details from Core Data into the text fields for displaying
if (currentPicture)
{
[titleField setText:[currentPicture title]];
[descriptionField setText:[currentPicture desc]];
if ([currentPicture smallPicture])
[imageField setImage:[UIImage imageWithData:[currentPicture smallPicture]]];
}
}
#pragma mark - Button actions
- (IBAction)editSaveButtonPressed:(id)sender
{
// If we are adding a new picture (because we didnt pass one from the table) then create an entry
if (!currentPicture)
self.currentPicture = (Pictures *)[NSEntityDescription insertNewObjectForEntityForName:#"Pictures" inManagedObjectContext:self.managedObjectContext];
// For both new and existing pictures, fill in the details from the form
[self.currentPicture setTitle:[titleField text]];
[self.currentPicture setDesc:[descriptionField text]];
if (imageField.image)
{
// Resize and save a smaller version for the table
float resize = 74.0;
float actualWidth = imageField.image.size.width;
float actualHeight = imageField.image.size.height;
float divBy, newWidth, newHeight;
if (actualWidth > actualHeight) {
divBy = (actualWidth / resize);
newWidth = resize;
newHeight = (actualHeight / divBy);
} else {
divBy = (actualHeight / resize);
newWidth = (actualWidth / divBy);
newHeight = resize;
}
CGRect rect = CGRectMake(0.0, 0.0, newWidth, newHeight);
UIGraphicsBeginImageContext(rect.size);
[imageField.image drawInRect:rect];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Save the small image version
NSData *smallImageData = UIImageJPEGRepresentation(smallImage, 1.0);
[self.currentPicture setSmallPicture:smallImageData];
}
// Commit item to core data
NSError *error;
if (![self.managedObjectContext save:&error])
NSLog(#"Failed to add new picture with error: %#", [error domain]);
// Automatically pop to previous view now we're done adding
[self.navigationController popViewControllerAnimated:YES];
}
// Pick an image from album
- (IBAction)imageFromAlbum:(id)sender
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[self presentViewController:imagePicker animated:YES completion:nil];
}
// Take an image with camera
- (IBAction)imageFromCamera:(id)sender
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
[self presentViewController:imagePicker animated:YES completion:nil];
}
// Resign the keyboard after Done is pressed when editing text fields
- (IBAction)resignKeyboard:(id)sender
{
[sender resignFirstResponder];
}
#end
available here : enter link description here
What do you think ??
Even though I now alone on this post, I wanted to post the answer !
I finally figured out why my textfield didn't appear which show who's has the hand on the compiler.
I actually subclassed the detail with a class wich implement methods to fill the table source with the coreData.Then, the supposed static cells were actually filled with these methods.
Which shows, to my humble opinion, that the .m overpass the IB.