I'd like to display 5 Buttons in a ScrollView Box but unfortunately the code I wrote has no effects on my UIButtons (I can't Scroll up or Down , can you tell me why ?
Thanks for you help, I spent a lot of hours on it (Rookie) but i still can't find the solution...
My Code :
FirstViewController.h :
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scroll;
UIButton *button;
UIButton *button2;
UIButton *button3;
}
#property (nonatomic, retain) IBOutlet UIButton *button;
#property (nonatomic, retain) IBOutlet UIButton *button2;
#property (nonatomic, retain) IBOutlet UIButton *button3;
#property(nonatomic,retain) IBOutlet UIScrollView *scroll;
#end
FirstViewController.m :
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize button;
#synthesize button2;
#synthesize button3;
#synthesize scroll;
- (IBAction)goToViewTwo {
}
- (void)viewDidload {
[super viewDidLoad];
[scroll setScrollEnabled:YES];
[scroll setContentSize:CGSizeMake (500, 1000)];
}
- (void)dealloc {
[super dealloc];
[button release];
[scroll release];
}
#end
Hierarchy in FirstView.xib:
View
Action Sheet
Text View
ScrollView
Button
Button
Button
About the Outlets :
Scrollview is linked to File's Owner with "Scroll"
View is linked to File's Owner as a "view"
I suppose you're implementing the scroll in Interface Builder and that the app is for iPad (for the contentSize). See if you have the same configuration in IB and in code, especially that [scroll setScrollEnabled:YES];
Related
In my iOS application, I have a main View Controller with three buttons, which work like a tab bar: when I click one of the buttons, a new view controller is invoked.
I tried to implement this via container view containers, so I tried following this guide (http://www.thinkandbuild.it/working-with-custom-container-view-controllers/) and invoke the presentDetailController method in the viewDidLoad of the main controller.
Actually, no views are showed: someone can help me figuring out why? Thanks.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIButton *btnOne;
#property (weak, nonatomic) IBOutlet UIButton *btnTwo;
#property (weak, nonatomic) IBOutlet UIButton *btnThree;
#property (weak, nonatomic) IBOutlet UIView *detailView;
- (IBAction)click:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "FirstViewController.h"
#interface ViewController ()
#property UIViewController *currentDetailViewController;
#end
#implementation ViewController
#synthesize btnOne, btnTwo, btnThree;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
FirstViewController *fvc = [[FirstViewController alloc]initWithString:#"I'm the first Controller!"];
[self presentDetailController:fvc];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)click:(id)sender
{
// button selection stuff
[self addDetailController:sender];
}
- (void)presentDetailController:(UIViewController*)detailVC{
//0. Remove the current Detail View Controller showed
if(self.currentDetailViewController){
[self removeCurrentDetailViewController];
}
//1. Add the detail controller as child of the container
[self addChildViewController:detailVC];
//2. Define the detail controller's view size
detailVC.view.frame = [self frameForDetailController];
//3. Add the Detail controller's view to the Container's detail view and save a reference to the detail View Controller
[self.detailView addSubview:detailVC.view];
self.currentDetailViewController = detailVC;
//4. Complete the add flow calling the function didMoveToParentViewController
[detailVC didMoveToParentViewController:self];
}
- (void)removeCurrentDetailViewController{
//1. Call the willMoveToParentViewController with nil
// This is the last method where your detailViewController can perform some operations before neing removed
[self.currentDetailViewController willMoveToParentViewController:nil];
//2. Remove the DetailViewController's view from the Container
[self.currentDetailViewController.view removeFromSuperview];
//3. Update the hierarchy"
// Automatically the method didMoveToParentViewController: will be called on the detailViewController)
[self.currentDetailViewController removeFromParentViewController];
}
- (CGRect)frameForDetailController{
// newFrame's height should be currentFrame's height minus buttons' height
CGRect detailFrame = CGRectMake(0, 0, self.detailView.bounds.size.width, self.detailView.bounds.size.height-self.btnOne.frame.size.height);
return detailFrame;
}
- (void)addDetailController:(id)sender {
FirstViewController *detailVC = [[FirstViewController alloc]initWithString:#"First button clicked"];
[self presentDetailController:detailVC];
}
#end
FirstViewController.h
#import <UIKit/UIKit.h>
#class ViewController;
#interface FirstViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UIButton *btnOne;
#property (weak, nonatomic) IBOutlet UIButton *btnTwo;
#property (weak, nonatomic) IBOutlet UIButton *btnThree;
- (id)initWithString:(NSString*)string;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController (){
NSString *text;
}
#end
#implementation FirstViewController
- (id)initWithString:(NSString*)string {
self = [super init];
if(self){
text = string;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.label.text = text;
}
#end
As part of creating FirstViewController, you are calling [super init] which produces a bare UIViewController. From your diagram, it seems as if you want to load a FirstViewController from your storyboard instead.
I suggest a sequence where you create your controller using instantiateViewControllerWithIdentifier:, then set a string property in the controller that you want to use as the label, and finally assign the string to the label when the controller's view loads.
Writing my first iphone app through this tutorial--I have a custom UIView with the method showDie and I have two UIView elements on my storyboard that I've hooked up to my ViewController. However, both the UIView elements have the error message "No visible #interface for 'UIView' declares the selector 'showDie'. I think that's because the UIViews aren't subclassing XYZDieView, but when I control-clicked from my Storyboard, only UIView appeared in the dropdown--no XYZDieView. I tried just changing the text manually in the ViewController.h, but that didn't work (I didn't think it would). Am I on the right track? How do I use my subclass? (xcode 5)
XYZDieView.m
-(void)showDie:(int)num
{
if (self.dieImage == nil){
self.dieImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
[self addSubview:self.dieImage];
}
NSString *fileName = [NSString stringWithFormat:#"dice%d.png", num];
self.dieImage.image = [UIImage imageNamed:fileName];
}
XYZViewController.h
#import <UIKit/UIKit.h>
#import "XYZDieView.h"
#interface XYZViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *sumLabel;
#property (strong, nonatomic) IBOutlet UIButton *rollButton;
#property (strong, nonatomic) IBOutlet UIView *leftDieView;
#property (strong, nonatomic) IBOutlet UIView *rightDieView;
#end
XYZViewController.m
#import "XYZViewController.h"
#import "XYZDiceDataController.h"
#interface XYZViewController ()
#end
#implementation XYZViewController
- (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)rollButtonClicked:(UIButton *)sender {
XYZDiceDataController *diceDataController = [[XYZDiceDataController alloc] init];
int roll = [diceDataController getDiceRoll];
int roll2 = [diceDataController getDiceRoll];
[self.leftDieView showDie:roll];
[self.rightDieView showDie:roll2];
int sum = roll + roll2;
NSString *sumText = [NSString stringWithFormat:#"Sum is %i", sum];
self.sumLabel.text = sumText;
}
#end
Yes you're right, the problem is subclassing. In order to have a view conform to a subclass in the interface builder you need to
Click on the UIView in your storyboard
Open the right inspector panel
Click on the third tab for identity inspector
Add your class
Then try to connect it to your ViewController again.
Edit: Afterwards you may need to cast XYZDieView myView = (XYZDieView*)leftDieView;
I don't understand why my project doesn't work.
I can open the window, but the scrollview wont scroll, which means I can't see the bottom of my UI. Why? I read answers to similar questions but they didn't help me fix my issue.
THIS IS THE DETAILVC.H
#interface DetailVC : UIViewController {
IBOutlet UIImageView *iv_main, *iv_ratings;
IBOutlet UITextField *tf_name, *tf_dob, *tf_age, *tf_weight, *tf_height,*tf_birthplace;
IBOutlet UITextView *tv_description;
IBOutlet UIButton *but_movies, *but_edit;
IBOutlet UINavigationBar *navbar;
IBOutlet UIScrollView *scrollView;
}
#property (nonatomic, retain) IBOutlet UIImageView *iv_main, *iv_ratings;
#property (nonatomic, retain) IBOutlet UITextField *tf_name, *tf_dob, *tf_age, *tf_weight, *tf_height, *tf_birthplace;
#property (nonatomic, retain) IBOutlet UITextView *tv_description;
#property (nonatomic, retain) IBOutlet UIButton *but_movies, *but_edit;
#property (nonatomic, retain) IBOutlet UINavigationBar *navbar;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
#end
THIS IS THE DETAILVC.M
#import "DetailVC.h"
#interface DetailVC ()
#end
#implementation DetailVC
#synthesize iv_main, iv_ratings, tf_age, tf_birthplace, tf_dob, tf_height, tf_name, tf_weight, tv_description, but_edit, but_movies,navbar, scrollView;
- (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 from its nib.
scrollView.contentSize = CGSizeMake(320, 1000);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
------Connection Inspector
http://s18.postimg.org/qjzrdz9a1/Schermata_2013_08_07_alle_16_47_19.png
------Scroll View attributed Inspector
http://s8.postimg.org/5eniaq8r9/Schermata_2013_08_07_alle_17_35_04.png
Is there a chance that the frame of your UIScrollView has the same size as contentSize? If yes, the UIScrollView will think it has enough frame to display all of the content.
I'm newbie in the iOS development and I'm working in a projecte that it uses iOS5 and Storyboarding. I would like to create a reusable component, like a button, with a custom view (inside the button there will be some images and labels, it will be a big button), to create some of them in the same view of a Storyboard.
So I've created a XIB file (ItemClothes.xib) with a UIButton and inside of it some UIImagesViews and a UILabel. Then I've created a subclass of UIButton (UIItemClothes.h and UIItemClothes.m), with properties for UIImageViews and UILabel components.
UIItemClothes.h
#import <UIKit/UIKit.h>
#import "SCClothes.h"
#interface UIItemClothes : UIButton
#property (nonatomic, strong) IBOutlet UIImageView *imageClothes;
#property (nonatomic, strong) IBOutlet UIActivityIndicatorView *loadingImage;
#property (nonatomic, strong) IBOutlet UIImageView *seasonIconClothes;
#property (nonatomic, strong) IBOutlet UIImageView *categoryIconClothes;
#property (nonatomic, strong) NSString *idClothes;
#property (strong, nonatomic) IBOutlet UILabel *lblProva;
#end
UIItemClothes.m
#import "UIItemClothes.h"
#implementation UIItemClothes
#synthesize imageClothes = _imageClothes;
#synthesize loadingImage = _loadingImage;
#synthesize seasonIconClothes = _seasonIconClothes;
#synthesize categoryIconClothes = _categoryIconClothes;
#synthesize idClothes = _idClothes;
#synthesize lblProva = _lblProva;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:#"ItemClothes" owner:self options:nil] objectAtIndex:0]];
}
return self;
}
#end
Then in the .XIB file I've set the class of UIButton as UIItemClothes, and make the relationships between XIB's UI components and my class properties.
So, after that, in the Storyboard, in the ViewController of one view I've written this code:
UIItemClothes *item = [[UIItemClothes alloc] initWithFrame:CGRectMake(0.0, 0.0, 200.0, 200.0)];
item.lblProva.text = #"test!";
[item.categoryIconClothes setImage:iconCategory];
item.seasonIconClothes.image = iconSeason;
[cell addSubview:item];
As you see, this component will be inside a TableViewCell, and the idea is to put more components (UIItemClothes) inside of it.
The problem is that the component is drawed but any outlet is set as I do in the code above.
Can anyone help me?
Thanks!
well, the problem has been resolved... Instead of having a custom subclass of UIButton, there will be needed a ViewController with all Outlets. Then in the other ViewController (StoryBoard) is initialized this new ViewController
I have two views. The first one is having 2 buttons and second one is having a label and a button. Am trying to change the text of the label based on the button pressed. In the code below, am calling an instance of second view and trying to change text in the label. But the problem is the text is not changing. Will appreciate if some one can help me here
#interface firstview : UIViewController {
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
}
#property(nonatomic, retain) IBOutlet UIButton *button1;
#property(nonatomic, retain) IBOutlet UIButton *button2;
-(IBAction)push:(UIButton *)sender;
#end
#import "firstview.h"
#import "secondview.h"
#implementation firstview
#synthesize button1;
#synthesize button2;
-(IBAction)push:(UIButton *)sender{
button1.tag = 1;
button2.tag = 2;
if(sender.tag == button1.tag){
secondview *v2 = [[secondview alloc]initWithNibName:#"secondview" bundle:Nil];
v2.title =#"first button";
v2.l1.text = #"BUTTON1";
[self.navigationController pushViewController:v2 animated:YES];
[v2 release];
}
else if(sender.tag == button2.tag){
secondview *v2 = [[secondview alloc]initWithNibName:#"secondview" bundle:Nil];
v2.title =#"Select";
v2.l1.text = #"BUTTON2";
[self.navigationController pushViewController:v2 animated:YES];
[v2 release];
}
}
#end
second view
#import <UIKit/UIKit.h>
#interface secondview : UIViewController {
IBOutlet UIButton *b2;
IBOutlet UILabel *l1;
}
#property(nonatomic, retain)IBOutlet UIButton *b2;
#property(nonatomic, retain)IBOutlet UILabel *l1;
-(IBAction)pop:(id)sender;
#end
#import "secondview.h"
#implementation secondview
#synthesize b2;
#synthesize l1;
-(IBAction)pop:(id)sender{
}
#end
At the time you are trying to set the label text, the view has not been loaded in your second view controller, so the label is nil.
Try moving the calls to after you push the view controller, or, better still (since only a view controller should change its views properties) have string properties on the second view controller for the label values, and set the label text value inside viewWillAppear.
From jrturton: The view is not been loaded in your second view controller, so the label is nil. What can you is declare a NSString property in secondview and you can set value of this property from firstview and then you can set this value to the label in viewWillAppear or viewDidLoad method.