By happenstance I have made a UITextView with both vertical AND horizontal scroll bars. This is pretty much a hack and I don't really understand why it works and was hoping for some insight. My original idea was to put a UITextView in a UIScrollView and have the scroll view supply my horizontal scrolling and I somehow got a horizontal scroll bar on the UITextView. I've whittled it down to the following code:
header
Code:
#import <UIKit/UIKit.h>
@interface DualScrollTextViewViewController : UIViewController {
UITextView *textViewDualScroll;
UIScrollView *backgroundScrollView;
}
@property(nonatomic, retain) IBOutlet UITextView *textViewDualScroll;
@property(nonatomic, retain) IBOutlet UIScrollView *backgroundScrollView;
@end
body
Code:
#import "DualScrollTextViewViewController.h"
@implementation DualScrollTextViewViewController
@synthesize textViewDualScroll;
@synthesize backgroundScrollView;
//fill the textview with a bunch of text.
-(void)populateTextView{
NSMutableString *bigText = [[NSMutableString alloc]init];
for(int i = 0; i <= 500; i ++){
[bigText appendString:@"1234 6789 "];
}
self.textViewDualScroll.text = bigText;
[bigText release];
}
//Create a UIScrollView and a UITextView. The text view is
//inside the scroll view and has the same size. The content
//size width of the scroll view is 1000.
-(void)initViews{
self.view.contentMode = UIViewContentModeTopLeft;
CGRect r;
r.size.width = 320;
r.size.height = 460;
r.origin.y = 0;
r.origin.x = 0;
CGSize s;
s.width = 1000;
s.height = r.size.height;
self.backgroundScrollView = [[UIScrollView alloc]initWithFrame:r];
self.backgroundScrollView.contentSize = s;
self.backgroundScrollView.contentMode = UIViewContentModeTopLeft;
self.backgroundScrollView.backgroundColor = [UIColor blueColor];
self.backgroundScrollView.showsVerticalScrollIndicator = NO;
self.backgroundScrollView.showsHorizontalScrollIndicator = NO;
self.backgroundScrollView.scrollEnabled = NO;
[self.view addSubview:self.backgroundScrollView];
r.origin.x = 0;
self.textViewDualScroll = [[UITextView alloc]initWithFrame:r];
self.textViewDualScroll.backgroundColor = [UIColor yellowColor];
self.textViewDualScroll.showsVerticalScrollIndicator = YES;
self.textViewDualScroll.showsHorizontalScrollIndicator = YES;
self.textViewDualScroll.scrollEnabled = YES;
self.textViewDualScroll.contentSize = s;
self.textViewDualScroll.font = [UIFont fontWithName:@"Courier" size:12];
[self.backgroundScrollView addSubview:textViewDualScroll];
}
//Not 100% on what this does.
-(void)doMagic{
int width = 1000;
CGRect r;
CGPoint p;
//resize text view to desired width
r = textViewDualScroll.frame;
r.size.width = width;
textViewDualScroll.frame = r;
//Set the bounds of the textview to be the same as the scroll.
//This causes most the magic....I think.
self.textViewDualScroll.bounds = backgroundScrollView.bounds;
//set the content offset for the scroll view so that it lines up
//with the textview.
p.y = 0;
p.x = self.textViewDualScroll.frame.origin.x;
backgroundScrollView.contentOffset = p;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[self initViews];
[self populateTextView];
[self doMagic];
}
- (void)viewDidUnload {
[textViewDualScroll release];
[backgroundScrollView release];
}
- (void)dealloc {
[super dealloc];
}
@end
The line
self.textViewDualScroll.bounds = backgroundScrollView.bounds; seems to make it all come together. If this line is left out then the UITextView remains as large as the UIScrollView and won't scroll horizontally. I have a few theories as to why this is happening but I'm really not sure.
Another odd artifact of this is that if the text is not large enough to need vertical scrolling then no scrolling is available. If you add a carriage return to the text view manually then the scroll bars become enabled. My thinking is that since UITextView doesn't like to horizontal scroll, it doesn't do any scrolling if vertical scrolling isn't needed. Adding the carriage return causes it to do some check to see if it should enable scrolling, thus enabling the horizontal scroll. There's a workaround for this as well, you just have to insert a carriage return at the end of the text and then delete it, but that's just annoying.
Feel free to use this code, but without understanding what it's doing, I'm not sure if it's a valid workaround or exploiting a bug (which may be fixed in the future).