How to create a scroll view programmatically - ios

How to create a simple scroll view when clicking a button in Xcode?
I have assigned the button and gave IBAction as press,
what to code to make a scroll view on this action?
-(IBAction)press
{
}

In .h file you must add delegate definition to your class declaration - something like this:
#interface someClass : NSObject <UIScrollViewDelegate>
In .m write somethink like this:
-(IBAction)press
{
UIScrollView *_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
_scrollView.backgroundColor = [UIColor clearColor];
_scrollView.userInteractionEnabled = YES;
_scrollView.delegate = nil;
[self.view addSubview:self.scrollView];
}
That's all! :)

Related

Add subview programmatically using instance method

I am trying to add a subview programmatically to my ViewController : UIViewController by using a method declared in my ThirdClass : NSObject class. Here is my code:
In the ViewController.m file I do:
- (void)viewDidLoad {
[super viewDidLoad];
ThirdClass *instanceOfThirdClass = [[ThirdClass alloc] init];
[instanceOfThirdClass createView];
}
And in my ThirdClass.m I declare the instance method:
-(void)createView{
NSLog(#"enter create app");
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(50, 0, 320, 100)];
[myView setBackgroundColor:[UIColor redColor]];
ViewController *instanceOfViewController = [[ViewController alloc]init];
[instanceOfViewController.view addSubview:myView];
}
so the problem apparently is that I was trying to add the created view to the class instance, the correct way to do it is the one posted by #gary-riches below,
You are attaching the view you create to a new instantiated view controller, but the view you are displaying is that of the one belonging ViewController.m. You need to add the view to the ViewController.m's view.
Update your createView method to handle a view:
-(void)createViewInView:(UIView *)aView{
NSLog(#"enter create app");
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(50, 0, 320, 100)];
[myView setBackgroundColor:[UIColor redColor]];
[aView addSubview:myView];
}
Then change your call to be:
[instanceOfThirdClass createViewInView:self.view];
Also, make sure you have the method signature in the header of ThirdClass.h. It should be:
-(void)createViewInView:(UIView *)aView;

How to remove a programmatically created subview by pressing a button within the subview

I currently have a barbutton:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneDate:)];
It calls the following action:
- (IBAction)doneDate:(id)sender{
[self removeDateView]
}
Which calls the following method:
- (void)removeDateView{
NSLog(#"subviews of view3.view: %#",self.View3.subviews);
[self.View3.subviews. makeObjectsPerformSelector: #selector(removeFromSuperview)];
}
The subview that I'm trying to remove is
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
At the moment it just deletes everything within that View, I can't seem to remove the view called containerView which has the datepicker and toolbar.
As erhnby stated, you could use a tag - which is a great method, but I always try to shy away from looping through a view's subviews whenever I can. Personally, I would make the view you are going to remove an instance variable, and when you want to remove it you can call remove directly on it... Just made a simple example that does this:
.h file:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController {
UIView *_containerView;
}
#end
.m file:
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (id)init {
self = [super init];
// create the bar button and set it as the right bar button on the navigation bar
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(removeDoneDate)];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// create the container view and add it as a subview
_containerView = [[UIView alloc] initWithFrame:CGRectMake(20, 100, 100, 100)];
_containerView.backgroundColor = [UIColor redColor];
[self.view addSubview:_containerView];
}
- (void)removeDoneDate {
// remove it
[_containerView removeFromSuperview];
}
#end
Results in this to start:
Press button...
(sorry, didn't realize the white on white would be that hard to see)
set tag for that will remove view
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
[containerView setTag:100];
and find it and removeFromSuperView
for (UIView* view in self.View3.subviews) {
if ([view isKindOfClass:[UIView class]] && view.tag == 100) {
[view removeFromSuperview];
}
}

How can I make this UILabel accessible to other classes?

I have a class which is a viewcontroller and it contains:
-(void)testNSTimer
{
[UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveEaseIn
animations:^{ self.view.welcomeBackLabel alpha = 0;} //welcomeBackLabel does not exist.
completion:nil];
}
However welcomeBackLabel is not available in this circumstance because it is created in the controller's view AKA self.view as shown in the following code:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
welcomeBackLabel = [[UILabel alloc] initWithFrame:CGRectMake(110, -20, 100, 120)]; //welcomeBackLabel is not available for other classes to use, but I want it to be.
[welcomeBackLabel setText:#"Welcome"];
[welcomeBackLabel setTextAlignment:NSTextAlignmentCenter];
UIFont *welcomeFont = [UIFont fontWithName:#"Helvetica-Bold" size:20];
welcomeBackLabel.font = welcomeFont;
[welcomeBackLabel setTextColor:[UIColor whiteColor]];
[welcomeBackLabel setAlpha:0.65];
[self addSubview:welcomeBackLabel];
}
I created a property however it is not detected by the viewcontroller's class even after importing the view's .h file. Can anybody should me the various ways I could have welcomeBackLabel be usable in my controller class?
EDIT:
For example, in my view's .h I have:
#property(nonatomic, retain) UILabel *welcomeBackLabel;
and I have
#import "view.h"
in my controller.m but its not detecting it as a usable property o.o
EDIT2:
Ok so if I have HomeScreenView *testView = [[HomeScreenView alloc]init]; then YES i can use the property fine ala testView.welcomebackLabel.etc . It just does not work when I have set the view for the controller using [self setView:testView] and then use self.view.welcomeBackLabel... Why is this?
In a UIViewController, self.view is returned as a UIView. If you "know" that it is a particular subclass of UIView, you need to cast it so you can access methods from the subclass. You could inline this, but for clarity:
MyUIView *v = self.view;
[v myMethod];
Or if you want inline:
[(MyUIView *) self.view myMethod];
If it is sometimes the right subclass you can test:
UIView *v = self.view;
if([v isKindOfClass:[MYUIView class]]) {
[(MyUIView *) self.view myMethod];
}
Create an #property in the .h file of your class and it should be accessible from other classes well.

UIScrollView is not scrolling in UiView

when I scroll on UIScrollView that not scrolling . Also I am setting scrollview's contentSize.
When I show one other subView and after when I show my view , it's scrolling.
You can see what is problem on this video . How can I solve this problem?
myViewController.h file
#import <UIKit/UIKit.h>
#interface myViewController : UIViewController
#property(nonatomic,retain)UIView * rightTabView;
#property(nonatomic,retain)UIView * leftTabView;
#property(nonatomic,retain)UIView * middleTabView;
#property(nonatomic,retain)UIScrollView *myscrollview;
#end
myViewController.m file
- (void)viewDidLoad
{
// Do any additional setup after loading the view from its nib.
[super viewDidLoad];
//create Tab views and addSubview
CGFloat barHeight=58;
self.rightTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+55,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
[self.view addSubview:self.rightTabView];
self.leftTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+5,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
self.leftTabView.backgroundColor=[UIColor redColor];
[self.view addSubview:self.leftTabView];
self.middleTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+55,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
[self.view addSubview:self.middleTabView];
//add Subview to leftTabView
myscrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(10, 10,300, 340)];
myscrollview.userInteractionEnabled=YES;
myscrollview.backgroundColor = [UIColor greenColor];
myscrollview.delegate = self;
[self.leftTabView addSubview:myscrollview];
myscrollview.contentSize = CGSizeMake(2000, 2000);
}
It looks like your middleTabView is obscuring your leftTabView (which is the superview of your scrollview). Either bring the leftTabView to the top of the view hierarchy:
[self.leftTabView.superview bringSubViewToFront:self.leftTabView];
or disable user interactions or visibility of your middleTabView (or add the leftTabView last).

Add Subview to main view with function of subview class

I want to add my custom UIView to my main view.
I want to use the function initWithTitle:description: like:
AchievementView *achievement = [[AchievementView alloc] initWithTitle:#"Test" description:#"The Descr"]];
But this doesn't work. tThe initWithTitle:description: function have to be implemented as class method.
AchievementView.h
#interface AchievementView : UIView
#property (strong) NSString *achievementTtl;
#property (strong) NSString *achievementDescr;
#property (strong) UIView *theAchievementView;
- (void)initWithTitle:(NSString*)achievementTitle description:(NSString*)achievementDescription;
- (void)showAchievement;
#end
AchievementView.m
-(void)initWithTitle:(NSString*)achievementTitle description:(NSString*)achievementDescription {
self.achievementTtl = achievementTitle;
self.achievementDescr = achievementDescription;
}
- (void)showAchievement {
// Create view popup
self.theAchievementView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 423)];
self.theAchievementView.layer.cornerRadius = 8;
self.theAchievementView.layer.masksToBounds = YES;
self.theAchievementView.layer.shadowRadius = 5;
self.theAchievementView.layer.shadowOpacity = .15;
[self.theAchievementView setBackgroundColor:[UIColor whiteColor]];
[self addSubview:self.theAchievementView];
}
Call the method in main view:
- (IBAction)share:(id)sender {
AchievementView *achievement = [[AchievementView alloc] init];
achievement.achievementTtl = #"Test";
achievement.achievementDescr = #"TestDEscr";
[achievement showAchievement];
}
I can't add the subview to the main view with this function.
I think the "self" is wrong. What should be there?
[self addSubview:self.theAchievementView];
You have 2 questions: how to initialize the view and how to add it to the screen.
You can use the initWithTitle:description: method, you just have to use it on an instance of the class, not the class itself:
[[AchievementView alloc] initWithTitle:#"Test" description:#"The Descr"]];
You are correct that you have the wrong self in your addSubview call. You need a reference to the parent view. You could pass it into your AchievementView class, but it is cleaner to manage that outside of the class.
I also noticed that AchievementView is a subclass of UIView, but you are creating another UIView inside it. It would be simpler to directly use the AchievementView. Your code should be similar to the below:
AchievementView.h
#interface AchievementView : UIView
#property (strong) NSString *achievementTtl;
#property (strong) NSString *achievementDescr;
- (id)initWithTitle:(NSString*)achievementTitle description:(NSString*)achievementDescription;
#end
AchievementView.m
- (id)initWithTitle:(NSString*)achievementTitle description:(NSString*)achievementDescription {
if (self = [super initWithFrame:CGRectMake(0, 0, 300, 423)]) {
self.achievementTtl = achievementTitle;
self.achievementDescr = achievementDescription;
self.layer.cornerRadius = 8;
self.layer.masksToBounds = YES;
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = .15;
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
Main view
- (IBAction)share:(id)sender {
AchievementView *achievement = [[AchievementView alloc] initWithTitle:#"Test" description:#"TestDEscr"];
[self.view addSubview:achievement];
}
Number one, you are never adding achievement as a subview of your main view. Basically you are creating a view offscreen, adding a view to that view, then moving on with whatever you want to do without ever moving the first view onto the screen.
As a minimum you should do this:
- (IBAction)share:(id)sender {
AchievementView *achievement = [[AchievementView alloc] init];
achievement.achievementTtl = #"Test";
achievement.achievementDescr = #"TestDEscr";
[achievement showAchievement];
[self addSubview:achievement];
}
Along with setting the frame size of achievement which is currently never set (and since most views by default mask to their layer bounds it will mask to (0,0,0,0)).
Then I would seriously reconsider how you are dealing with views and subviews. If you do things properly, your initwithtitle will work just fine.

Resources