Unable to implement simple view scrolling in iOS - objective-c

I'm having a hard time implementing a simple scroll on my detail view.
The app is straightforward with a Master and Detail views.
When the user taps an item on Master, the Detail view is pushed with larger photo, blog text and etc.
I would like the entire Detail view to scroll, so if the picture is tall, or the text is long, they can scroll vertically to see/read more. I do not want the user to scroll these items individually. It should feel like webpage scrolling.
Currently my Detail view loads OK but I can't make it scroll.
My DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController {
IBOutlet UILabel *postTextLabel; // wired to Text Label
IBOutlet UILabel *postAuthorNameLabel; // wired to Author Label
}
#property (strong, nonatomic) id detailItem;
#end
My DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
- (void)configureView
{
if (self.detailItem) {
NSDictionary *post = self.detailItem;
NSString *postText = [post objectForKey:#"post_text"];
NSString *postAuthorName = [post objectForKey:#"post_author_name"];
postTextLabel.text = postText;
postAuthorNameLabel.text = postAuthorName;
}
}
#end
Structure on IB:
Any ideas on what's missing to make this work?

I would do the following:
1)(optional)turn your View into a scrollview by dragging it into the view in the scruture list on the side.
2)link the scrollView into your viewcontroller .h and make an Outlet connection something like this
#property (strong, nonatomic) IBOutlet UIScrollView *scroller;
(make sure you add #synthesize in the .m if you add this manually)
and make sure it is connected in IB!
3)set the contentsize of the scrollview in viewDidLoad method
scroller.contentSize = CGSizeMake(320,550);
NOTE: IBOutlet UILabel *postTextLabel; should actually probably be a UITextView so you can access ContentSize
Which would allow for the following.
CGRect frame = postTextLabel.frame;
frame.size = postTextLabel.contentSize;
postTextLabel.frame = frame;
scroller.contentSize = CGSizeMake(320, frame.size.height+200);//200 or how ever much space is above the textView
and again that only works if you use a UITextView
for ipad replace 320 with 768 or 1024, or whichever depending on orientation
The best way to connect it in IB is like this holding down control and dragging to the .h file
and make sure it is set to automatic like in the picture, and pointing to> the .h of your view.
Adding it like this also automatically adds the #synthesize for you.
Make sure UserInteractionsEnabled are checked here for our scrollview

Related

UIButton label doesn't appear on UIImageView

I user Interface Builder to position a UIButton and a UIImageView superimposed.
In the code, I change button label if image exists
In Example.h
#property (strong, nonatomic) IBOutlet UIButton *takePicture;
#property (strong, nonatomic) IBOutlet UIImageView *image;
In Example.m
[self.image setImage:aPhoto];
(...)
NSString *pictureButtonTitle = myCondition#"Changer la photo":#"Ajouter une photo";
(...)
[self.takePicture setTitle:pictureButtonTitle forState:UIControlStateNormal];
I use this code for a view, and I see "Change picture" correctly on my picture when myCondition is true.
But in another view, nothing appears !! WHY ?
You could either do it in the interface builder - as you did, or do it in your viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view bringSubviewToFront:self.button];
}
Arranging the outlets in the IB as you did mean that the lower object will be on top of the others... The button will be "front"/on top when it is placed below all other objects as you shown in the screenshot.
If you wish to arrange the outlets differently, you could use these methods as well:
[self.view insertSubview:self.button aboveSubview:self.imageView];
Or:
[self.view insertSubview:self.imageView belowSubview:self.button];
Well, I found out : in Interface Builder, it seems that the order you place your objects matters
If you place an UIImageView before UIButton, it works well.
I see the label
But if you do the reverse : button is under the image.
And the label is not displayed
I still don't know if it's the only way to rearrange these items ?

Content moved after when back to first viewcontroller

I have 2 viewcontrollers in a navigationController.
In the first viewcontroller I have a UIButton that open the second viewcontroller.
When second viewController is load I can see the "back" button on top-left of the screen.
Now, when I come back to the first viewController the content is some points upper than last time.
Like the next image http://imperiosweb.com/tmp/sample.png
Now, first ViewController has a UIScrollView that has the content.
FirstViewController.h
...
#interface FirstViewController : UIViewController{
IBOutlet UIScrollView *Scroller;
}
#property (weak, nonatomic) IBOutlet UIScrollView *Scroller;
...
FirstViewController.m
...
#implementation FirstViewController
...
#synthesize Scroller = _scroller;
...
- (void)viewDidLoad
{
[self.Scroller setBounces:YES];
...
}
I don't know if is the center of the scrollView or something else, I was trying to set center, works but doesn't repair the problem (content moved)
- (void)viewDidAppear:(BOOL)animated {
[self.view setCenter:self.Scroller.center];
self.Scroller.frame = CGRectMake(0,0,320,416);
self.Scroller.contentSize = CGSizeMake(320, (550 + self.Scroller.contentOffset.y));
[self.Scroller setCenter:(CGPointMake(160.0,208.0))];
}
What can I do to fix content like first time (App just launched)?
Thanks!

Obejct-C / Xcode Not able to add/change text in UITextView

For some reason, i'm not able to change or add text in my UITextView from code.
I have made Outlet and connected (All in IB) - nothing happens.
Even tried to add -setNeedsDisplay
Do i need to set some property ? - This i driving me nuts....
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextViewDelegate> {
UITextView *textInfoView;
}
#property (nonatomic, retain) IBOutlet UITextView *textInfoView;
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
textInfoView.text = #"Test";
}
-(void)viewDidAppear:(BOOL)animated{
textInfoView.text = #"Test";
textInfoView.text = [textInfoView.text stringByAppendingString:#"Line2"];
[textInfoView setNeedsDisplay];
It seems, really strange that this code doesn't update the text inside the UITextView. I have tried and it works for me ... I think that you don't have correctly linked the Outlet in interface builder, or you don't have associated your view controller to your view ...
UPS - Got it...
Forgot to #synthesize...
For some reason i did not get warning or "setter error" in Xcode 4.4, maybe it's a version bug ?

How do I access or manipulate variables of one class from another in Xcode

I am a novice to IOS programming hence struggling a bit with the below problem. I will do my best to describe the problem and any help is greatly appreciated.
I have the following created:
AboutViewController (.h, .m and .xib ) which has two subviews called - mainView, infoView. mainView and infoView interfaces are created in the XIB file.
TestView ( View to deal with initiating, toggling between mainView and infoView )
TestView.h is as follows:
#interface TestView : UIView {
IBOutlet UIView *mainView;
IBOutlet UIView *infoView;
UILabel *lbltitle;
UIImageView *imgIcon;
IBOutlet UITextView *txtInfo1;
IBOutlet UITextView *txtInfo2;
IBOutlet UITextView *txtInfo3;
}
#property (nonatomic, retain) IBOutlet UILabel *lbltitle;
#property (nonatomic, retain) IBOutlet UIImageView *imgIcon;
TestView.m is as follows:
#import "TestView.h"
#import <QuartzCore/QuartzCore.h>
#implementation TestView
#synthesize lbltitle, imgIcon;
-(void)awakeFromNib
{
[self addSubview:mainView];
}
In portrait mode the views are working great but when it comes to landscape mode, the views are all kinda screwed up. I tried to use the XIB but I guess you can only do so much so I decided to do this programmatically.
In the AboutViewController.m, I am trying to override willAnimateRotationToInterfaceOrientation method and place the objects based on the orientation. When I put breakpoints, I can see that code is being called except it is not translating into the UI i.e., no change in the UI. What am I doing wrong ? Should I be approaching this in a different way. Any suggestions or guidance is greatly appreciated.
- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
TestView *t = [[TestView alloc]init];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
[t.imgIcon setFrame:CGRectMake(10,74,165,190)];
[t.lbltitle setFrame:CGRectMake(20, 10, 387, 21)];
}
else
{
[t.imgIcon setFrame:CGRectMake(10,74,165,190)];
[t.lbltitle setFrame:CGRectMake(189, 10, 387, 21)];
}
}
Well the particular problem is you manipulate a view that you just created using
TestView *t = [[TestView alloc]init];
You don't display the view anywhere, so it sits in memory. You can apply all changes you want, but to be able to see them, you must first display the view:
Find the appropriate parent and do:
[parentview addSubview:t];
In more general terms you shouldn't be creating new views in the rotation handling code.

Setting the initial value of a UILABEL

I'm trying to create a simple Quiz app (I'm a beginner), when I launch the app I want a UILabel to show the first question (of an array of questions). I'm having some trouble with setting the initial value.
I've done a couple of attempts, whiteout success. I my QuizAppDelegate.h file I declare my UILabel like this:
IBOutlet UILabel * questionField;
In my main .m file I have tried the following:
- (id)init {
[super init];
questions = [[NSMutableArray alloc] init];
// Not working
questionField = [[UILabel alloc] init];
[questionField setText:#"Hello"];
// Working
NSLog(#"Hello");
[self defaultQuestions];
// [self showQuestion];
return self;
}
Another thing I have tried is the following in QuizAppDelegate:
#property (nonatomic, retain) IBOutlet UILabel *questionField;
- (void)changeTitle:(NSString *)toName;
And in the .m file:
#synthesize questionField;
- (id)init {
[super init];
questions = [[NSMutableArray alloc] init];
// Not working
[self changeTitle:#"Hello"];
// Working
NSLog(#"Hello");
[self defaultQuestions];
// [self showQuestion];
return self;
}
-(void)changeTitle:(NSString *)toName {
[questionField setText:toName];
}
Any tips on how to solve this would be great!
// Anders
Hopefully you're not actually putting code into main.m. On iOS, you rarely modify that file.
Since you're doing everything in the AppDelegate, let's keep it there (as opposed to creating a new UIViewController). Let's start with the basics.
Adding the Label as an instance variable
You're doing this correctly—inside the curly braces of the .h file, put the line
IBOutlet UILabel * questionField;
Then, declare the corresponding property, and make sure to synthesize it in the .m file.
#property (nonatomic, retain) IBOutlet UILabel *questionField;
#synthesize questionField // in the .m file
Adding the UILabel in Interface Builder
Open up MainWindow.xib. Drag a UILabel from the Library to the Window that represents your app's window. Then Control-Drag from the AppDelegate object (the third icon on the left in Xcode 4; it'll be labelled in the Document window in IB 3). You'll see a little black window come up—select the option called questionField to make the connection.
See this link for screenshots and how to make connections in IB. The same applies in Xcode 4.
Changing the text
You don't need a separate method to change the text—just modify the label's text property.
Pick a method that'll be called when the app launches (applicationDidFinishLaunching:WithOptions: is a good place to do it in), and put the following code:
questionField.text = #"Hello";
And that's it!
Code
QuizAppDelegate.h
#import <UIKit/UIKit.h>
#interface QuizAppDelegate : NSObject <UIApplicationDelegate> {
IBOutlet UILabel *questionField;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UILabel *questionField;
#end
QuizAppDelegate.m
#import "QuizAppDelegate.h"
#implementation QuizAppDelegate
#synthesize window=_window;
#synthesize questionField;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Add the tab bar controller's current view as a subview of the window
[self.window addSubview:self.questionField];
[self.window makeKeyAndVisible];
self.questionField.text = #"Hello";
return YES;
}
- (void)dealloc
{
[_window release];
[questionField release];
[super dealloc];
}
#end
If you're creating the label programmatically, then you have to add the label to the view:
[self.view addSubview:questionField];
This assumes that you have a ViewController. If not, and you're doing this directly in the AppDelegate (a very bad idea, by the way), then do
[self.window addSubview:questionField];
If you're creating it in the IB, make sure you set up the connections.
You should not both add the UILabel in the IB and instantiate it programmatically. Only call alloc if you are creating it programmatically. Otherwise, if using the IB, skip that part. You created it already with the xib.
I suspect that you have either not created your Interface Builder layout properly - either you have missed the control out all together or more likely you have not connected that control to the questionField outlet in yout header file.
You need to drag a UILabel view into the main view and then connect it to the correct line in your header file.
You shouldn't be using your main.m like that at all. In fact, you should almost certainly never do anything with it. Try creating a UIViewController subclass and practicing your quiz with that. (Add the UILabel to the IB file and then connect the outlet.) Perhaps use the View-Based Application template while you are practicing.
This is a good answer:
"You're doing this correctly—inside the curly braces of the .h file, put the line
IBOutlet UILabel * questionField;"
I was trying to change the value of mylabel.text and the screen didn't update the label with this.value. I included the {IBOutlet UILabel * mylabel} and it works like a charm!
So this answer is valid to change the text of a label programmatically!
Thanks