push to vc from UIView class under a view controller - ios

created a class,
GSSFeatureScreenLocationTabView : UIView,
to add multiple view into a scroll view,
the view comes up with buttons which are linked to a selector that is supposed to push to another view controller, It sends the placeID back up but from some reason doesn't push to the next view controller
GSSFeatureScreenLocationTabView.h
#import "featureScreenViewController.h"
#interface GSSFeatureScreenLocationTabView : UIView
{
UIImageView* imageView;
UILabel* titleLabel;
UILabel* distanceLabel;
UILabel* descriptionLabel;
UIButton* pushButton;
}
#property (nonatomic) NSString* placeID;
-(void)setLocationInfo:(NSString*)ID title:(NSString*)title distance:(double)distance description:(NSString*)description imageURL:(NSString*)imageURL;
#end
GSSFeatureScreenLocationTabView.m
#import "GSSFeatureScreenLocationTabView.h"
#import "GSSLocationDetailViewController.h"
#implementation GSSFeatureScreenLocationTabView
#synthesize placeID = _placeID;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 144, 140)];
titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(20, 148, 107, 21)];
distanceLabel = [[UILabel alloc]initWithFrame:CGRectMake(20, 177, 107, 21)];
descriptionLabel = [[UILabel alloc]initWithFrame:CGRectMake(20, 206, 107, 91)];
pushButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 144, 317)];
[titleLabel setText:#""];
[distanceLabel setText:#""];
[descriptionLabel setText:#""];
[descriptionLabel setLineBreakMode:NSLineBreakByWordWrapping];
[pushButton setTitle:#"" forState:UIControlStateNormal];
[pushButton addTarget:self action:#selector(pushToLocation) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:imageView];
[self addSubview:titleLabel];
[self addSubview:distanceLabel];
[self addSubview:descriptionLabel];
[self addSubview:pushButton];
}
return self;
}
-(void)setLocationInfo:(NSString *)ID title:(NSString *)title distance:(double)distance description:(NSString *)description imageURL:(NSString *)imageURL
{
_placeID = ID;
[titleLabel setText:title];
[distanceLabel setText:[NSString stringWithFormat:#"%f", distance]];
[descriptionLabel setText:description];
UIImage* image = [UIImage imageNamed:imageURL];
[imageView setImage:image];
}
-(void) pushToLocation
{
NSLog(#"%s", __FUNCTION__);
featureScreenViewController* fsvc = [[featureScreenViewController alloc]init];
[fsvc pushToLocationWithID:_placeID];
}
#end
in featureScreenViewController.m
- (void)viewDidLoad
{
#define isiPhone5 ([[UIScreen mainScreen] bounds].size.height == 568)?TRUE:FALSE
if (isiPhone5)
{
// this is iphone 4 inch
[scroller setFrame:CGRectMake(0, 251, 320, 317)];
}
else
{
[scroller setFrame:CGRectMake(0, 251, 320, 229)];
}
[self addLocationViews];
}
-(void)addLocationViews
{
int count = (int)[_placeArray count];
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(152*count, 317)];
for (int i = 0; i<count; i++) {
_placeObject = [_placeArray objectAtIndex:i];
GSSFeatureScreenLocationTabView * view = [[GSSFeatureScreenLocationTabView alloc]initWithFrame:CGRectMake((152*i), 0, 144, 317)];
[view setLocationInfo:[_placeObject placeID] title:[_placeObject placeName] distance:[_placeObject distacne] description:#"description" imageURL:#"noImage.png"];
[scroller addSubview:view];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
self.navigationController.navigationBarHidden = YES;
}
-(void) pushToLocationWithID:(NSString*)placeID
{
NSLog(#"\n%s \nplaceID:%#\n\n", __FUNCTION__, placeID);
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
GSSLocationDetailViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"GSSLocationDetailViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
the function -(void) pushToLocationWithID:(NSString*)placeID is called and the log shows the function and placeID, However it doesn't push to the location view controller.
tried creating a button just to link a segue to it and called the performSegue with identifier, doesn't reach prepare for segue and still doesn't push.
However using the same code from another page in an IBAction and it works. Is there someway to call super or something so it goes into the navController and pushes it ?
If i do presentViewController just to test modal like shown above it shows
Warning: Attempt to present <GSSLocationDetailViewController: 0xab85110> on <featureScreenViewController: 0xab9c230> whose view is not in the window hierarchy!
but if i do
[self.navigationController pushViewController:vc animated:YES];
it doesn't show anything in the log and doesn't push.
made a new project with same concept at http://www.narula-tech.com/testScrollPush.zip

You are in a UIView (GSSFeatureScreenLocationTabView) and you are allocating a new viewController (VC2: featureScreenViewController) from there and you are pushing another viewController (VC3: GSSLocationDetailViewController) from there.
But actually your view is in another viewController VC1 and you need to push VC3 from there and not from VC2 which you are allocating but is not "in the scene" or better, in the window hierarchy.
So you should control touches from the viewController and not from the UIView..for this reason the name: view**CONTROLLER**.
Another thing but not related:
name of class should began with the first letter capitol:
So not:
featureScreenViewController* fsvc;
but:
FeatureScreenViewController* fsvc;

Related

IOS response button click in another viewController

Here is the main idea
+---MyViewController.m----+ +---BtnOnClickResp.m-----+
| | EventTouchUpInside: | |
| Button ---------------------------------------> OnBtnClick() |
| | textView.text=#"blabla"| | |
| *textView <------------------------------------------ + |
| | | |
+-------------------------+ +------------------------+
I want to test if button OnClick could be pressed in another controller like this:
MyViewController.h
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController
#property (nonatomic, strong) UITextView *textView;
+(id) sharedInstance;
#end
MyViewController.m
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
BtnOnClickResp.h
#import <UIKit/UIKit.h>
#interface BtnOnClickResp : UIViewController
#end
BtnOnClickResp.m
#import "BtnOnClickResp.h"
#import "MyViewController.h"
#interface BtnOnClickResp ()
#end
#implementation BtnOnClickResp
- (void) onBtnClick: (UIButton *) btn{
NSLog(#"btn was click but I am in another controller");
MyViewController *control = [MyViewController sharedInstance];
control.textView.text = #" I am setting this content in another view cheers!!!";
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The main idea is draw/add a button view in the MyViewController and make the response to click code in another controller, I thought the action assignment code:
[btn addTarget:self action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
if we change the self to the actually controller we want to use then the click event will be dispatched to that controller
But it seems not working.
Really a beginner of ios development would be happy if you don't downvote this beginner's question.
EIDT
After taking the advice as #Mike suggested,
I change the MyViewController.m to this:
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController (){
//here is the change , I made a private ref of the controller
BtnOnClickResp *respContl;
}
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:respContl action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
respContl = [[BtnOnClickResp alloc] init];
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end
Now I could see the NSLog of btn was click but I am in another controller but the view content still kept not changed to #" I am setting this content in another view cheers!!!" as it expected to be in BtnOnClickResp.m
This is the launch code in AppDelagate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *control = [[MyViewController alloc] init];
[self.window setRootViewController:control];
[self.window setBackgroundColor:[UIColor greenColor]];
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
You are adding Target
[btn addTarget:[[BtnOnClickResp alloc] init] action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
to
[BtnOnClickResp alloc] init]
is Wrong
Because it will create new instance and add listener to it.
However you are try to access action in other instance
You have 4 solutions
Create shared instance of BtnOnClickResp and assign target to it
Pass the self of BtnOnClickResp to the MyViewController on and assign it
Create Delegate
Post Notification
Declare a property of BtnOnClickResp and set it as button target.
#import "MyViewController.h"
#import "BtnOnClickResp.h"
#interface MyViewController ()
#property(nonatomic, strong) BtnOnClickResp onClickRespObj;
#end
#implementation MyViewController
#synthesize textView;
+ (id) sharedInstance{
static MyViewController *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (id)init{
if(self = [super init]){
self.onClickRespObj = [[BtnOnClickResp alloc] init];
}
return self;
}
- (void) setUpScene{
textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 500, 400) ];
[textView setBackgroundColor:[UIColor grayColor]];
[textView setFont:[UIFont systemFontOfSize:18]];
[textView setTextColor:[UIColor blackColor]];
textView.text = #"";
[self.view addSubview:textView];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 50 , 400, 50)];
[btn setTitle:#"Click Me" forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor yellowColor]];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn addTarget:self.onClickRespObj action:#selector(onBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpScene];
// Do any additional setup after loading the view.
}
#end

UIImagePickerController duplicates content on close

When I bring up a UIImagePickerController and then close it, it duplicates the content in my modal window. Below are the before and after pictures:
Here's the code that shows the image picker:
-(void) choosePhotos
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setDelegate:self];
[imagePicker setAllowsEditing:YES];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:imagePicker animated:YES completion:nil];
}
Here's the rest of my code (if needed):
-(id) init
{
self = [super init];
if (self)
{
[self.navigationItem setTitle:#"Deposit"];
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleDone target:self action:#selector(cancel)];
[self.navigationItem setLeftBarButtonItem:closeButton];
toItems = #[#"Account...5544", #"Account...5567"];
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
[self.view addGestureRecognizer:recognizer];
}
return self;
}
-(void) hideKeyboard
{
for (UITextField *field in [scrollView subviews])
{
[field resignFirstResponder];
}
}
-(void) cancel
{
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [toItems count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [toItems objectAtIndex:row];
}
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[self.view setBackgroundColor:[UIColor whiteColor]];
UILabel *toLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, 50, 100)];
[toLabel setText:#"To:"];
toPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(130, -30, 220, 100)];
[toPicker setDataSource:self];
[toPicker setDelegate:self];
UILabel *amountLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 70, 100)];
amountLabel.lineBreakMode = NSLineBreakByWordWrapping;
amountLabel.numberOfLines = 0;
[amountLabel setText:#"Check Amount:"];
UITextField *amountField = [[UITextField alloc] initWithFrame:CGRectMake(130, 100, 270, 100)];
[amountField setPlaceholder:#"Enter Amount"];
[amountField setReturnKeyType:UIReturnKeyDone];
[amountField setKeyboardType:UIKeyboardTypeDecimalPad];
UILabel *imagesLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, 70, 100)];
imagesLabel.lineBreakMode = NSLineBreakByWordWrapping;
imagesLabel.numberOfLines = 0;
[imagesLabel setText:#"Check Images:"];
UIButton *imagesButton = [[UIButton alloc] initWithFrame:CGRectMake(120, 200, 244, 99)];
[imagesButton setBackgroundImage:[UIImage imageNamed:#"photos.png"] forState:UIControlStateNormal];
[imagesButton addTarget:self action:#selector(choosePhotos) forControlEvents:UIControlEventTouchUpInside];
CGRect bounds = [[UIScreen mainScreen] bounds];
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, bounds.size.width, bounds.size.height)];
[scrollView setAlwaysBounceVertical:YES];
[scrollView setShowsVerticalScrollIndicator:YES];
[scrollView addSubview:toLabel];
[scrollView addSubview:toPicker];
[scrollView addSubview:amountLabel];
[scrollView addSubview:amountField];
[scrollView addSubview:imagesLabel];
[scrollView addSubview:imagesButton];
[self.view addSubview:scrollView];
}
I recommend you use viewDidLoad as the place to create and add your views:
- (void)viewDidLoad {
[super viewDidLoad];
//init and add your views here
//example view
self.someLabel = [[UILabel alloc] init];
self.someLabel.text = #"someExampleText";
[self.view addSubview:self.someLabel];
}
And either viewWillAppear or viewDidLayoutSubviews as the place to configure their sizes (i prefer viewDidLayoutSubviews so i'll use it as an example):
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.someLabel.frame = CGRectMake(kMargin,kMargin,kLabelWidth,kLabelHeight);
}
Of course, in order to do this you need to have a reference to all the views you wish to configure this way by creating a property to them in the interface:
#interface YourViewController ()
#property (nonatomic, strong) UILabel *someLabel;
#end;
static CGFloat const kMargin = 20.0f;
static CGFloat const kLabelHeight = 30.0f;
static CGFloat const kLabelWidth = 100.0f;
Also, it is recommended you avoid using hard coded values for their sizes (doing it like CGRectMake(20,20,100,70) but this it not completely wrong.
Not using hard coded values does not mean setting them yourself, it just means to make their values more readable (and on most cases, dynamic).
In my example, i created kMargin, kLabelHeight and kLabelWidth, meaning that anyone who looks at this code will understand what they mean, they will know what to change if needed, and these values can be used in other places.
For example, you could have 4 labels, and in order to keep them all following the same layout rules, all of them will use the kMargin value on the origin.x.
You could also, instead of using a static value for the width, you can implement a dynamic value, like this:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat labelWidth = self.view.bounds.size.width - (kMargin * 2);
self.someLabel.frame = CGRectMake(kMargin,kMargin,labelWidth,kLabelHeight);
}
What i did here is to make my label to have the same width as my super view, but i made it account for the left and the right margins (by taking the total view width and reducing twice the margin value).
Since we are doing this on the viewDidLayoutSubviews method, which gets called whenever the superview changes its size (for example, orientation change) this will ensure your UILabel can be shown on any size of view and orientation without extra code to handle 'specific cases'.
Your UI elements are being added to your view every time viewWillAppear is called. This is called when your image picker dismisses and returns to your view, so they're being duplicated. Either check to see whether your UI elements already exist before creating them again, or do your UI setup in the viewDidLoad method which will only be run once. You could try this perhaps, using a BOOL property to keep track:
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
if (!self.alreadyAppeared) {
self.alreadyAppeared = YES;
// Create labels and buttons
}
}

How go to MainStoryboard's initial view after guidance page view showed?

How to enter storyboard's initial view when click the button in the scroll view.
My storyboard consists of the following:
[Navigation Controller] -> [TableView Controller] -> [DetailView Controller]
My code:
#import "AppDelegate.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
[self GuidePage];
return YES;
}
-(void)GuidePage
{
UIScrollView *scro=[[UIScrollView alloc]initWithFrame:self.window.bounds];
scro.pagingEnabled=YES;
_currentScro=scro;
scro.scrollEnabled=YES;
scro.bounces=NO;
scro.showsHorizontalScrollIndicator=NO;;
scro.delegate=self;
UIImageView *imgView1=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Guide1.png"]];
imgView1.frame=CGRectMake(0, 0, 320, 480);
UIImageView *imgView2=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"Guide2.png"]];
imgView2.frame=CGRectMake(320, 0, 320, 480);
UIButton *btnEnter= [[UIButton alloc] initWithFrame:CGRectMake(400, 200, 100, 100)];
[btnEnter setTitle:#"Enter" forState:UIControlStateNormal];
[scro addSubview:imgView1];
[scro addSubview:imgView2];
[scro addSubview:btnEnter];
[btnEnter addTarget:self action:#selector(gotoMainStoryboard) forControlEvents:UIControlEventTouchUpInside];
scro.contentSize=CGSizeMake(320*2, scro.frame.size.height);
UIPageControl *page=[[UIPageControl alloc]initWithFrame:CGRectMake(0, 400, 320, 20)];
page.numberOfPages=2;
_pageControl=page;
[page addTarget:self action:#selector(changeCurrentPage:) forControlEvents:UIControlEventValueChanged];
page.backgroundColor=[UIColor redColor];
page.currentPage=0;
[self.window addSubview:scro];
[self.window addSubview:page];
}
-(void) gotoMainStoryboard
{
NSLog(#"goto");
}
-(void)changeCurrentPage:(UIPageControl *)sender
{
[_currentScro setContentOffset:CGPointMake(sender.currentPage*320, 0)];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ((int)scrollView.contentOffset.x%320==0) {
_pageControl.currentPage=(int)scrollView.contentOffset.x/320;
}
}
#end
In your
-(void) gotoMainStoryboard
{
[self performSegueWithIdentifier:#"segue name" sender:nil];
}
This will bring next viewcontroller on button click.

how to create a popup uipicker and uitextfield for iOS 7?

I need to add pickers to my textboxes, but can't figure out how to get them to work. I've gone through a number of tutorials that show you how to start from scratch, which is kinda useless if you have an existing app and you're wanting to add functionality, for the most part they're not very helpful.
I'm looking for something very similar to the image below. The one displayed below is obviously a UIDatepicker, but ideally
I'm looking for a custom picker for "place", "term", and "gate".
So for now, skip the UIDatepicker item, and focus on the custom picker item.
One more thing, this is iOS7, and I am using storyboards AND arc!
I ran across this (http://www.youtube.com/watch?v=BtmQp5aP304) which was really helpful, but again it's starting from scratch. What I can't figure out is how to implement this within my existing code. So I'm looking for a walk-through, a tutorial that someone can point me at to get me started.
There is this on stackoverflow ->
how to pop up datePicker when text filed click and disappear when editing done
Which gave me a few ideas, but not exactly what I'm looking for, tried the suggestions and ended up with more errors than anything else.
Thanks.
#interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
#implementation ViewController
{
UIPopoverController *popoverController;
NSString *currentPick;
….
}
.
.
.
-(void)makePicker{
UIPickerView *picker = [[[UIPickerView alloc]init]autorelease];
picker.frame = CGRectMake(0, 50, 320, 1000);
picker.showsSelectionIndicator = YES;
picker.delegate = self;
UIButton *done = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[done setBackgroundImage:[UIImage imageNamed:#"Save.png"] forState:UIControlStateNormal];
[done setFrame:CGRectMake(260, 10, 50, 30)];
[done addTarget:self action:#selector(doneButton:) forControlEvents:UIControlEventTouchUpInside];
UIButton *cancel = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[cancel setBackgroundImage:[UIImage imageNamed:#"Cancel.png"] forState:UIControlStateNormal];
[cancel setFrame:CGRectMake(10, 10, 50, 30)];
[cancel addTarget:self action:#selector(cancelButton:) forControlEvents:UIControlEventTouchUpInside];
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
UIActionSheet *pickerAction = [[[UIActionSheet alloc]initWithTitle:[cells objectAtIndex:indexPath.section] delegate:self cancelButtonTitle:nil destructiveButtonTitle:Nil otherButtonTitles:nil]autorelease];
[pickerAction addSubview:picker];
[pickerAction addSubview:done];
[pickerAction addSubview:cancel];
[pickerAction showInView:self.view];
pickerAction.frame = CGRectMake(0,[UIScreen mainScreen].bounds.size.height - 330,320, 350);
}else
{
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
[popoverView addSubview:picker];
[popoverView addSubview:done];
[popoverView addSubview:cancel];
[popoverContent.view addSubview:popoverView];
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverController presentPopoverFromRect:<your frame> inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
popoverContent.contentSizeForViewInPopover = CGSizeMake(320, 260);
[popoverView release];
[popoverContent release];
}
}
.
.
.
// mainArray here is a NSArray of several arrays, these arrays contain the titles for different selections… e.g. #[fontArray,colourArray,nameArray]
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [[mainArray objectAtIndex:clickedAt] count];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [[mainArray objectAtIndex:clickedAt] objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
currentPick = [[mainArray objectAtIndex:clickedAt] objectAtIndex:row];
}
- (void)doneButton:(UIButton *)button
{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
UIActionSheet *as = (UIActionSheet *)[button superview];
[as dismissWithClickedButtonIndex:0 animated:YES];
}
else
[popoverController dismissPopoverAnimated:YES];
// save your selections here using currentPick object
}
- (void)cancelButton:(UIButton *)button
{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
UIActionSheet *as = (UIActionSheet *)[button superview];
[as dismissWithClickedButtonIndex:0 animated:YES];
}
else
[popoverController dismissPopoverAnimated:YES];
}
Enjoy your Picker ;)
check this, make a full screen UIView , a UIImageView , a UIPickerView and two UIButtons (save and cancel)in .xib then
make their outlets in your .h file:
#property (retain, nonatomic) IBOutlet UIView *bg_view;
#property (retain, nonatomic) IBOutlet UIImageView *bg_customImageView;
#property (retain, nonatomic) IBOutlet UIPickerView *myPicker;
- (IBAction)cancelOut:(UIButton *)sender;
- (IBAction)saveOut:(UIButton *)sender;
#property (retain, nonatomic) IBOutlet UIButton *saveButton;
#property (retain, nonatomic) IBOutlet UIButton *cancelButton;
then in .m file:
-(void)customPickerShow
{
[self.bg_view setBackgroundColor:[UIColor colorWithRed:0.3 green:0.25 blue:0.05 alpha:0.5]];
[self.bg_view setHidden:NO];
self.navigationController.toolbarHidden = YES;
self.navigationController.navigationBarHidden = YES;
[self showMyPicker];
}
-(void)showMyPicker
{
[self.myPicker reloadAllComponents];
[self animatePicker];
}
-(void)animatePicker
{
self.cancelButton.frame = CGRectMake((framewidth/2) - 130, frameheight, 70, 1);
self.saveButton.frame = CGRectMake((framewidth/2) + 60, frameheight, 70, 1);
self.bg_customImageView.frame = CGRectMake((framewidth/2) - 140, frameheight, 280, 1);
[UIView beginAnimations:Nil context:Nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
self.bg_customImageView.frame = CGRectMake((framewidth/2) - 150, frameheight - 230, 300, 300);
self.cancelButton.frame = CGRectMake((framewidth/2) - 130, frameheight - 220, 50, 50);
self.saveButton.frame = CGRectMake((framewidth/2) + 80, frameheight - 220, 50, 50);
[UIView commitAnimations];
}
- (IBAction)cancelOut:(UIButton *)sender {
self.navigationController.navigationBarHidden = NO;
self.navigationController.toolbarHidden = NO;
[self.bg_view setHidden:YES];
}
- (IBAction)saveOut:(UIButton *)sender {
// save here your selections
self.navigationController.navigationBarHidden = NO;
self.navigationController.toolbarHidden = NO;
[self.bg_view setHidden:YES];
}
call this [self customPickerShow]; function to make it work..
This will look like action sheet with picker and buttons.. you can customize with your choice of background image and your choice of frame in animatePicker function
Don't forget to make this bg_view at top of other views and make it sethidden by default
Purely using UIStoryboard probably won't be able to either solve the project, or not the best way. This is my solution.
1) Create a CustomPicker
2) Define your Datasource and Delegate
3) Attached the CustomPicker to the inputView of the target TextField.
4) you can set it up at the delegate method
-(Bool)textFieldShouldBeginEditing:(UITextField *)textField
In this approach, we add the Picker by coding it (not by UIStoryboard).
I have this demo project to show this purpose.

Restrict my project to portrait only leaving photo view's in landscape/portrait

I want my whole project to run in portrait mode only and only the view that's for viewing the photo's can turn on landscape same as if using the facebook (we view photo's they turn landscape also but other view's remains in portrait) i want to know that how it's done as i have a table view that has images that i get from the DB from the server and every particular data contains different number's of photo's so now i want that after the user select's the photo's they should open up fully and can be viewed in landscape and in portrait as well i did tried
I am working with ios6
- (BOOL)shouldAutorotate
{
return NO;
}
implementing in all the view's so that they can remain in portrait but still they turn in landscape how should i restrict it and please can any one tell me that in one of my class i have images in table view(loaded from the DB) and i have another class that open's up the selected photo from the table
My PhotoView.m class
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dic = [photos objectAtIndex:indexPath.row];
NSLog(#" *** url is %#",[dic objectForKey:#"url"]);
[self.delegate showPhotoAtUrl:[dic objectForKey:#"url"]];
}
My PhotoViewController.h class
#import <UIKit/UIKit.h>
#interface PhotoViewController : UIViewController <UIScrollViewDelegate>
{
NSString *url;
UIButton *doneButton;
}
#property (nonatomic, retain) UIImageView *imageView;
- (id) initWithPhotoUrl:(NSString *)photoUrl;
#end
and PhotoViewController.m class
#import "PhotoViewController.h"
#interface PhotoViewController ()
#end
#implementation PhotoViewController
#synthesize imageView;
- (id) initWithPhotoUrl:(NSString *)photoUrl
{
self = [super init];
if(self) {
url = [photoUrl retain];
}
return self;
}
- (void)dealloc
{
[url release];
self.imageView = nil;
[doneButton release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.tag = 1;
spinner.center = self.view.center;
[spinner startAnimating];
[self.view addSubview:spinner];
[spinner release];
[self performSelectorInBackground:#selector(loadPhotoData) withObject:nil];
doneButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
[doneButton addTarget:self action:#selector(doneTouched) forControlEvents:UIControlEventTouchUpInside];
[doneButton setTitle:#"done" forState:UIControlStateNormal];
[doneButton setBackgroundColor:[UIColor clearColor]];
doneButton.frame = CGRectMake(2, 2, 60, 30);
[self.view addSubview:doneButton];
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.title = #"";
self.navigationController.navigationBarHidden = YES;
}
- (void) doneTouched
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void) loadComplete:(NSData *)imageData
{
if(!imageData) return;
UIActivityIndicatorView *spinner = (UIActivityIndicatorView *)[self.view viewWithTag:1];
if(spinner) {
[spinner stopAnimating];
[spinner removeFromSuperview];
}
UIImage *img = [UIImage imageWithData:imageData];
float scale = MIN(self.view.frame.size.width/img.size.width, self.view.frame.size.height/img.size.height);
self.imageView = [[[UIImageView alloc] initWithImage:img] autorelease];
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width*scale, self.imageView.image.size.height*scale);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.imageView.center = scrollView.center;
scrollView.delegate = self;
scrollView.contentSize = self.imageView.frame.size;
scrollView.minimumZoomScale = 1;
scrollView.maximumZoomScale = 2;
[scrollView addSubview:self.imageView];
[self.view addSubview:scrollView];
[scrollView release];
[self.view bringSubviewToFront:doneButton];
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (void) loadPhotoData
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
[self performSelectorOnMainThread:#selector(loadComplete:) withObject:imageData waitUntilDone:NO];
[pool drain];
}
#end
and in the main class i have have this method that calls the PhotoViewController to load the selected photo
- (void) showPhotoAtUrl:(NSString *)url
{
PhotoViewController *vc = [[PhotoViewController alloc] initWithPhotoUrl:url];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
}
Now my problem is how should i get the images after getting selected from the table to be open up in the same type of the view that open's up in FB app (open's the selected photo in portrait/landscape compatible view) i am only able to get one photo in my PhotoViewController class can any one tell me how can i add all the photo's to the PhotoViewController class so that i get the effect that i want ?... Any code help will be very helpful .. Thanks in Advance for contributing your time
In Short i have two things to do :
I have to restrict my project to only portrait mode leaving only the photo's view to have landscape/portrait compatibility.
I am currently having the photo's in my table view that i want on selection to open up in the same style(landscape/portrait compatibile) as FB or other app's do while viewing the photo's.
These only work on iOS 6.0
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return (UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft);
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
The method will return which orientation mode to use first.
Below are supportedInterfaceOrientations:
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskLandscape
UIInterfaceOrientationMaskAll
UIInterfaceOrientationMaskAllButUpsideDown
For iOS > 4.0
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
Other ViewControllers will have
-(BOOL)shouldAutorotate { return NO; }
-(BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation{
return NO;
}

Resources