I have a UISegmentedControl where the first control will display the text within a UITextView while the second control displays a scrollable UIImageView.
In the initial startup, if I switch to the second control, the image displays and switching back to the first control, the image disappears and the UITextView shows.
However, when I switch to the second control the 2nd time and switch back to the first control, the image is still there and I cannot get the UITextView to show anymore.
My code has it to where the image is hidden and the text is shown in the first control, and vice versa in the second control.
Why was it working the first time, but then not working the second time I switched between controls?
What am I doing wrong?
Thanks
-(void)viewDidLoad
{
self.scrollView.delegate = self;
self.textView.text = #"THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST.";
self.textView.hidden = NO;
}
-(void)setScroller
{
CGSize scrollableSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
[self.scrollView setContentSize:scrollableSize];
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"] ];
self.imageView.frame = CGRectMake(0, 0, self.scrollView.frame.size.width, self.view.frame.size.height);
self.scrollView.backgroundColor = [UIColor blackColor];
self.scrollView.minimumZoomScale = 1.0 ;
self.scrollView.maximumZoomScale = self.imageView.image.size.width / self.scrollView.frame.size.width;
//self.scrollView.zoomScale = 1.0;
[self.scrollView addSubview:self.imageView];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (IBAction)segmentedControl:(UISegmentedControl *)sender
{
if (self.segmentedControl.selectedSegmentIndex == 0)
{
// Display apppropriate info for About
self.imageView.hidden = YES;
self.textView.hidden = NO;
}
else
{
self.imageView.hidden = NO;
self.textView.hidden = YES;
[self setScroller];
}
}
You should remove [self setScroller]; from the - (IBAction)segmentedControl:(UISegmentedControl *)sender method, and put it in -(void)viewDidLoad instead. You're calling [self setScroller]; every time you switch to the second segment.
Your code should look like:
-(void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.delegate = self;
[self setupScroller];
}
-(void)setupScroller
{
// Set contentSize
CGSize scrollableSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
self.scrollView.contentSize = scrollableSize;
// Add textView
self.textView.text = #"THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST. THIS IS A TEST.";
self.textView.hidden = NO;
// Add ImageView
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
self.imageView.frame = CGRectMake(0, 0, self.scrollView.frame.size.width, self.view.frame.size.height);
self.imageView.hidden = YES;
[self.scrollView addSubview:self.imageView];
// Configure Zoom Scales and backgroundColor
self.scrollView.backgroundColor = [UIColor blackColor];
self.scrollView.minimumZoomScale = 1.0 ;
self.scrollView.maximumZoomScale = self.imageView.image.size.width / self.scrollView.frame.size.width;
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
- (IBAction)segmentedControl:(UISegmentedControl *)sender
{
if (self.segmentedControl.selectedSegmentIndex == 0)
{
// Display appropriate info for About
self.imageView.hidden = YES;
self.textView.hidden = NO;
}
else
{
self.imageView.hidden = NO;
self.textView.hidden = YES;
}
}
Your problem probably is that you creating a lot of instances of "imageView"
To solve your problem I suggest:
-(void)setScroller
{
CGSize scrollableSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
[self.scrollView setContentSize:scrollableSize];
if(self.imageView == nil) {
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
[self.scrollView addSubview:self.imageView];
}
self.imageView.frame = CGRectMake(0, 0, self.scrollView.frame.size.width, self.view.frame.size.height);
self.scrollView.backgroundColor = [UIColor blackColor];
self.scrollView.minimumZoomScale = 1.0 ;
self.scrollView.maximumZoomScale = self.imageView.image.size.width / self.scrollView.frame.size.width;
//self.scrollView.zoomScale = 1.0;
[self.imageView setNeedsDisplay];
[self.imageView setImage:[UIImage imageNamed: #"test.png"]];
}
I've put only the Alloc of the self.imageView + the addSubView to the if,
All the rest are out side,
Now it will work
Related
I want to zoom in/out UIScrollView that contains a UIImageView. With my code below I am only able to scroll the scroll view contents but cannot zoom it.
My view hierarchy looks like this:
- (UIView *) containerView
-- (UIView *) contentView
--- (UIScrollView *) scrollView
---- (UIImageView *) self.imageView
Code:
UIView *previousContentView = nil;
for (NSInteger i = 0; i < 2; i++) {
contentView = [self addRandomColoredView];
[containerView addSubview:contentView];
[containerView.topAnchor constraintEqualToAnchor:contentView.topAnchor].active = true;
[containerView.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor].active = true;
scrollView = [self addRandomScrollView];
[contentView addSubview:scrollView];
self.imageView = [[UIImageView alloc] init];
[self.imageView setImage:[imagesArray objectAtIndex:i]];
[self.imageView setTranslatesAutoresizingMaskIntoConstraints:false];
[scrollView addSubview:self.imageView];
if (previousContentView) {
[VerticalSeparatorView addSeparatorBetweenView:previousContentView secondView:contentView];
NSLayoutConstraint *width = [contentView.widthAnchor constraintEqualToAnchor:previousContentView.widthAnchor];
width.priority = 250;
width.active = true;
} else {
[containerView.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor].active = true;
}
[contentView.topAnchor constraintEqualToAnchor:scrollView.topAnchor].active = true;
[contentView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor].active = true;
[contentView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor].active = true;
[contentView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor].active = true;
[scrollView.topAnchor constraintEqualToAnchor:self.imageView.topAnchor].active = true;
[scrollView.bottomAnchor constraintEqualToAnchor:self.imageView.bottomAnchor].active = true;
[scrollView.leadingAnchor constraintEqualToAnchor:self.imageView.leadingAnchor].active = true;
[scrollView.trailingAnchor constraintEqualToAnchor:self.imageView.trailingAnchor].active = true;
previousContentView = contentView;
}
[containerView.trailingAnchor constraintEqualToAnchor:previousContentView.trailingAnchor].active = true;
- (UIView *)addRandomColoredView
{
UIView *someView = [[UIView alloc] init];
someView.translatesAutoresizingMaskIntoConstraints = false;
[someView setBackgroundColor:[UIColor blackColor]];
return someView;
}
-(UIScrollView *)addRandomScrollView
{
UIScrollView *scrollView = [[UIScrollView alloc] init];
[scrollView setDelegate:self];
[scrollView setTranslatesAutoresizingMaskIntoConstraints:false];
[scrollView setBackgroundColor:[UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]];
[scrollView setMaximumZoomScale:2.5f];
[scrollView setMinimumZoomScale:0.5f];
[scrollView setZoomScale:scrollView.minimumZoomScale];
return scrollView;
}
#pragma mark - UIScrollViewDelegate
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
I believe the scrollView is getting its contentSize because it is showing the image and I can scroll. Why can't I zoom in or zoom out?
You have to specify a delegate for your scroll view, and then implement viewForZoomingInScrollView to tell it to zoom the image view:
- (UIView *)addScrollViewWithImageView {
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = false;
scrollView.maximumZoomScale = 200.0;
scrollView.minimumZoomScale = 0.1;
scrollView.delegate = self;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"test.png"]];
imageView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:scrollView];
[scrollView addSubview:imageView];
[NSLayoutConstraint activateConstraints:#[
[imageView.topAnchor constraintEqualToAnchor:scrollView.topAnchor],
[imageView.leftAnchor constraintEqualToAnchor:scrollView.leftAnchor],
[imageView.rightAnchor constraintEqualToAnchor:scrollView.rightAnchor],
[imageView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor]
]];
return scrollView;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return scrollView.subviews.firstObject;
}
And then to populate these zoomable scroll views with image views, your viewDidLoad might look like:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *previousContentView = nil;
for (NSInteger i = 0; i < 3; i++) {
UIView *contentView = [self addScrollViewWithImageView];
[self.view.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor].active = true;
[self.view.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor].active = true;
if (previousContentView) {
[HorizontalSeparatorView addSeparatorBetweenView:previousContentView secondView:contentView];
NSLayoutConstraint *height = [contentView.heightAnchor constraintEqualToAnchor:previousContentView.heightAnchor];
height.priority = 250;
height.active = true;
} else {
[self.view.topAnchor constraintEqualToAnchor:contentView.topAnchor].active = true;
}
previousContentView = contentView;
}
[self.view.bottomAnchor constraintEqualToAnchor:previousContentView.bottomAnchor].active = true;
}
Try MWPhotoBrowser. It has built in scroll and zoom functionality. You will get more than you need. Good Luck.
Hi i am beginner in ios and in my project i am adding UIImage on UIScrollview and i have added tap gesture on UIImage
When we double click on UIImage then image should be zooming full screen size on view controller
After the full screen size image we can zoom it like any way what we want(i mean using like pinch zoom effect)here my requirement is when we double click on image then image need to set it's original position i have tried my level best but i did not get result please help me
my code is below:
#import "ViewController2.h"
#interface ViewController2 ()
{
UIScrollView * myScroll;
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
UIImageView * _imageView;
}
#end
#implementation ViewController2
- (void)viewDidLoad
{
[super viewDidLoad];
isFullScreen = FALSE;
myScroll = [[UIScrollView alloc] init];
myScroll.frame = self.view.bounds;
myScroll.contentSize = CGSizeMake(_imageView.frame.size.width, _imageView.frame.size.height);
myScroll.maximumZoomScale = 4.0;
myScroll.minimumZoomScale = 1.0;
myScroll.clipsToBounds = YES;
myScroll.delegate = self;
myScroll.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:myScroll];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[_imageView setClipsToBounds:YES];
_imageView.userInteractionEnabled = YES;
_imageView.image = [UIImage imageNamed:#"ram.jpeg"];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen:)];
tapper.numberOfTapsRequired = 1;
[_imageView addGestureRecognizer:tapper];
[myScroll addSubview:_imageView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}
-(void)imgToFullScreen:(UITapGestureRecognizer*)sender {
if (!isFullScreen) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
prevFrame = _imageView.frame;
[_imageView setFrame:[[UIScreen mainScreen] bounds]];
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[_imageView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = FALSE;
}];
return;
}
}
#end
I did some modifications in your code as like below try it .Check it give your wanted output or not.
#interface ScrollViewController ()<UIScrollViewDelegate>{
UIScrollView * myScroll;
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
UIImageView * _imageView;
CGAffineTransform trans;
}
#end
#implementation ScrollViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
isFullScreen = FALSE;
myScroll = [[UIScrollView alloc] init];
myScroll.frame = [UIScreen mainScreen].bounds;
myScroll.contentSize = CGSizeMake(prevFrame.size.width, prevFrame.size.height);
myScroll.maximumZoomScale = 4.0;
myScroll.minimumZoomScale = 1.0;
myScroll.clipsToBounds = YES;
myScroll.delegate = self;
myScroll.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:myScroll];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[_imageView setClipsToBounds:YES];
_imageView.userInteractionEnabled = YES;
_imageView.image = [UIImage imageNamed:#"img.png"];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen:)];
tapper.numberOfTapsRequired = 2;
[_imageView addGestureRecognizer:tapper];
[myScroll addSubview:_imageView];
prevFrame = _imageView.frame;
trans = _imageView.transform;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}
-(void)imgToFullScreen:(UITapGestureRecognizer*)sender {
if (!isFullScreen) {
myScroll.contentSize = prevFrame.size;
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
_imageView.frame = [UIScreen mainScreen].bounds;
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
myScroll.contentSize = CGSizeMake(prevFrame.size.width, prevFrame.size.height);
_imageView.transform = trans;
_imageView.frame = prevFrame;
NSLog(#"%# %#",NSStringFromCGSize(myScroll.contentSize),NSStringFromCGRect(prevFrame));
}completion:^(BOOL finished){
isFullScreen = FALSE;
}];
return;
}
}
I'm new to iOS development, and now working on an iOS app mainly using UINavigationController and UITableViewController.
The problem I try to solve is the UITableView (Custom tableView cell) layout broken bug on the root viewController. This happens when I back from a child viewController to the root viewController.(Left: Original, Right: Wrong Layout) It looks like UITableView position is moved for some reason, but I'm not sure why.
In MainViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
viewFrame = self.view.bounds;
[self loadHeader];
[self loadTable];
self.view.backgroundColor = [UIColor whiteColor];
numberOfCellRow = 20;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)loadView {
[super loadView];
}
- (void)loadHeader {
CGRect headerFrame = viewFrame;
headerFrame.size.width = self.view.frame.size.width;
headerFrame.size.height = 200;
self.headerView = [[HeaderView alloc] initWithFrame:CGRectIntegral(headerFrame)];
[self.view addSubview:self.headerView];
NSLog(#"header loaded");
}
- (void)loadTable {
CGRect tableFrame = CGRectMake(viewFrame.origin.x, viewFrame.origin.y + 150,
viewFrame.size.width, viewFrame.size.height-150);
self.customTableView = [[UITableView alloc] initWithFrame:CGRectIntegral(tableFrame)];
self.customTableView.backgroundColor = [UIColor clearColor];
//set delegates
self.customTableView.delegate = self;
self.customTableView.dataSource = self;
//set custom cell
UINib *nib = [UINib nibWithNibName:#"CardViewCell" bundle:nil];
[self.customTableView registerNib:nib forCellReuseIdentifier:#"Cell"];
self.customTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.customTableView];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"cell loaded");
dispatch_async(dispatch_get_main_queue(), ^{
[self loadData:indexPath];
});
}
- (void)loadData: (NSIndexPath *)indexPath {
_tableCell.titleLabel.text = [[_articles objectAtIndex:indexPath.row] title];
NSLog(#"%#", [[_articles objectAtIndex:indexPath.row] title]);
[_tableCell setNeedsLayout];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
_tableCell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
_tableCell.backgroundColor = [UIColor clearColor];
[_tableCell.contentView setUserInteractionEnabled: NO];
// add touch events
[_tableCell.button addTarget:self
action:#selector(cellPressed:withEvent:)
forControlEvents:UIControlEventTouchUpInside];
NSLog(#"%#", NSStringFromCGRect(tableView.frame));
return _tableCell;
}
In CardViewCell.m
- (void)drawRect:(CGRect)rect {
//self.backgroundColor = [UIColor colorWithRed:228/255.0f green:228/255.0f blue:228/255.0f alpha:1.0f];
NSLog(#"%f", rect.origin.x);
self.backgroundColor = [UIColor clearColor];
[self drawCardView];
[self drawCardImage];
[self drawButton];
[self drawLabels];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
- (void)drawCardImage {
_cardViewBounds = _cardView.bounds;
CGRect imageFrame = _cardViewBounds;
imageFrame.size.height = _cardViewBounds.size.height/2+40;
_cardImage = [[UIImageView alloc] initWithFrame:CGRectIntegral(imageFrame)];
_cardImage.image = [UIImage imageNamed:#"sampleImage"];
_cardImage.backgroundColor = [UIColor grayColor];
_cardImage.clipsToBounds = YES;
_cardImage.contentMode = UIViewContentModeScaleAspectFill;
_cardImage.userInteractionEnabled = YES;
_cardImage.tag = 100;
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(3.0, 3.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.cardView.bounds;
maskLayer.path = maskPath.CGPath;
_cardImage.layer.mask = maskLayer;
[self.cardView addSubview:_cardImage];
}
- (void)drawCardView {
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect frame = CGRectMake(15, 25, (int)screen.size.width-30, 200);
_cardView.layer.cornerRadius = 3;
_cardView.backgroundColor = [UIColor greenColor];
_cardImage.userInteractionEnabled = YES;
_cardImage.tag = 101;
_cardView.frame = CGRectIntegral(frame);
CALayer *caLayer = _cardView.layer;
caLayer.frame = _cardView.frame;
caLayer.shadowRadius = 3.0f;
caLayer.shadowOpacity = 0.4f;
caLayer.shadowOffset = CGSizeMake(0.0f, 3.0f);
caLayer.shouldRasterize = YES;
// retina screen resolution
[caLayer setRasterizationScale:[[UIScreen mainScreen] scale]];
[caLayer setShouldRasterize:YES];
[self addSubview:_cardView];
}
- (void)drawButton {
CGRect buttonSize = CGRectMake(_cardViewBounds.size.width-100, _cardViewBounds.size.height/2+10, 50, 50);
_button = [[UIButton alloc] initWithFrame:CGRectIntegral(buttonSize)];
_button.layer.cornerRadius = 25;
_button.backgroundColor = [UIColor colorWithRed:0 green:169.0f/255.0f blue:244.0f/255.0f alpha:1.0f];
_button.userInteractionEnabled = YES;
_button.tag = 102;
//_button.titleLabel.text = #"+";
[_button setTitle:#"+" forState:UIControlStateNormal];
[_button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:30.0]];
CALayer *caButtonLayer = _button.layer;
caButtonLayer.frame = _button.frame;
caButtonLayer.shadowRadius = 3.0f;
caButtonLayer.shadowOpacity = 0.2f;
caButtonLayer.shadowOffset = CGSizeMake(0.0f, 3.0f);
caButtonLayer.shouldRasterize = YES;
// retina screen resolution
[caButtonLayer setRasterizationScale:[[UIScreen mainScreen] scale]];
[caButtonLayer setShouldRasterize:YES];
[self.cardView addSubview:_button];
}
- (void)drawLabels {
CGRect titleLabelSize = CGRectMake( 10, _cardViewBounds.size.height-50, _cardViewBounds.size.width-20, 40);
_titleLabel = [[UILabel alloc] initWithFrame:CGRectIntegral(titleLabelSize)];
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.numberOfLines = 2;
_titleLabel.userInteractionEnabled = YES;
_titleLabel.tag = 103;
[_titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:15.0]];
[_cardView addSubview:_titleLabel];
[_cardView sendSubviewToBack:_titleLabel];
}
- (void)prepareForReuse {
[super prepareForReuse];
for (UIView *subView in [self.contentView subviews]) {
[subView removeFromSuperview];
}
}
The code of this app is on this link.
Any ideas to solve this?
Your thoughts and help will be hugely appreciated.
the reason the view misplace is due to the _cardView.frame is CGRectZero when disappear, and I didn't find the solve yet.
you can add those to see the change.
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
NSLog(#"viewWillLayoutSubviews cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
NSLog(#"viewDidLayoutSubviews cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
NSLog(#"viewWillDisappear cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
NSLog(#"viewDidDisappear cardView %#",NSStringFromCGRect(self.tableCell.cardView.frame));
}
I think you can learn more about life-cycle about viewController and Cell.
LifeCycle
by the way, when I watching your code, I don't know if you want to use xib or only code to programming. Like the code below, this is init from code but you try to get from xib.
just my opinion.
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// make self from nib file
UINib *nib = [UINib nibWithNibName:#"HeaderView" bundle:nil];
self = [nib instantiateWithOwner:nil options:nil][0];
self.backgroundColor = [UIColor colorWithRed:0 green:169.0f/255.0f blue:244.0f/255.0f alpha:1.0f];
CGRect frame = CGRectZero;
frame.size.width = [[UIScreen mainScreen] bounds].size.width;
frame.size.height = 200;
[self setFrame:frame];
}
return self;
}
I'm simply trying to place an image into scroll view which is in a main view using purelayout.
And what i'm taking right now is;
Note that view with red background is scroll view. And also the image is not scrollable.
- (void)loadView {
self.view = [[UIView alloc] init];
[self.scrollView addSubview:self.photoView];
[self.view addSubview:self.scrollView];
[self.view setNeedsUpdateConstraints];
}
- (void)updateViewConstraints {
if (!_didSetupConstraints) {
...
...
...
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
[self.photoView autoPinEdgeToSuperviewEdge:ALEdgeRight];
self.didSetupConstraints = YES;
}
[super updateViewConstraints];
}
- (UIImageView *)photoView {
if (!_photoView) {
_photoView = [UIImageView newAutoLayoutView];
_photoView.backgroundColor = [UIColor whiteColor];
}
return _photoView;
}
- (UIScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [UIScrollView newAutoLayoutView];
_scrollView.backgroundColor = [UIColor redColor];
_scrollView.maximumZoomScale = 2.0;
_scrollView.minimumZoomScale = 0.5;
}
return _scrollView;
}
Ok, it seems working well with two changes i did.
Firstly i set self.photoView size manually.
[self.photoView autoSetDimensionsToSize:CGSizeMake([HelperModel screenWidth], [HelperModel screenHeight] -[HelperModel viewHeight:self.navigationController.navigationBar] -20.0)];
HelperModel.m
#implementation HelperModel
+ (CGFloat)screenWidth {
return [[UIScreen mainScreen] bounds].size.width;
}
+ (CGFloat)screenHeight {
return [[UIScreen mainScreen] bounds].size.height;
}
+ (CGFloat)viewHeight:(UIView *)view {
return CGRectGetHeight(view.frame);
}
+ (CGFloat)photoDetailHeight {
return [HelperModel screenHeight] -20;
}
#end
Secondly,
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
for zooming feature and if the zoomed image exceeds the bounds of scroll view, then the image can be scrolled properly.
I am working on a reader app. when you read one magazine, it will display first five pages and download the rest pages one by one. there is a scrollview to view the thumbnail image of pages. At the beginning, if the page needs downloading, the corresponding thumbnail view's alpha value is set to 0.5 (the thumbnail images are in the file,no need to download). when the page is downloaded, i will update the thumbnail view's value to 1.0. I use one operation to download the page, and when one is downloaded i use delegate to set thumbnail view's alpha.
But when i update thumbnail view's alpha value, it still the same as the beginning. it seems the alpha has no effect. I wonder is there anything wrong with my code? some snippets are as follows:
In the PageViewController.m
- (void)loadView
{
[super loadView];
//...
[self createSlideUpViewIfNecessary];
[self downloadPages];
}
- (void)createSlideUpViewIfNecessary {
if (!slideUpView) {
[self createThumbScrollViewIfNecessary];
// create container view that will hold scroll view and label
CGRect frame = CGRectMake(CGRectGetMinX(self.view.bounds), CGRectGetMaxY(self.view.bounds), CGRectGetWidth(self.view.bounds), CGRectGetHeight(thumbScrollView.frame));
slideUpView = [[UIView alloc] initWithFrame:frame];
[slideUpView setBackgroundColor:[UIColor blackColor]];
[slideUpView setOpaque:NO];
[slideUpView setAlpha:0.75];
[[self view] addSubview:slideUpView];
// add subviews to container view
[slideUpView addSubview:thumbScrollView];
}
}
- (void)createThumbScrollViewIfNecessary {
if (!thumbScrollView) {
float scrollViewHeight = THUMB_HEIGHT + THUMB_V_PADDING;
float scrollViewWidth = CGRectGetWidth(self.view.bounds);
thumbScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, scrollViewWidth, scrollViewHeight)];
[thumbScrollView setCanCancelContentTouches:NO];
[thumbScrollView setClipsToBounds:NO];
// now place all the thumb views as subviews of the scroll view
// and in the course of doing so calculate the content width
float xPosition = THUMB_H_PADDING;
for (int i = 0; i < magazine.pageNum ; i++) {
Page *page = [magazine.pages objectAtIndex:i];
NSString *name = page.pageName;
NSString *mfjName =[name stringByReplacingOccurrencesOfString:#".mfj" withString:#"Small.mfj"];
UIImage *thumbImage = nil;
if([mfjName hasSuffix:#".mfj"])
thumbImage = [Reader loadMfjFromSprOrCache:magazine MFJ:mfjName];
ThumbImageView *thumbView;
if (thumbImage) {// sometimes mfjname is 0 which means white page in normal and black thumbnail in thumbnail scrollview.
if (!mThumbnailSizeUpdated) {
mThumbnailWidth = thumbImage.size.width;
mThumbnailHeight = thumbImage.size.height;
mThumbnailSizeUpdated = YES;
}
thumbView = [[ThumbImageView alloc] initWithImage:thumbImage];
} else {
CGRect thumbFrame;
if (mThumbnailSizeUpdated) {
thumbFrame = CGRectMake(0, 0, mThumbnailWidth, mThumbnailHeight);
} else {
mThumbnailWidth = 80;
mThumbnailHeight = 100;
thumbFrame = CGRectMake(0, 0, mThumbnailWidth, mThumbnailHeight);
}
thumbView = [[ThumbImageView alloc] initWithFrame:thumbFrame];
}
NSString *mfjPath= [[magazine getDownloadPath] stringByAppendingPathComponent:name];
if (![magazine getFileInfo:name]&&![[NSFileManager defaultManager] fileExistsAtPath:mfjPath]) {
thumbView.alpha = 0.5;
}
[thumbView setBackgroundColor:[UIColor blackColor]];
[thumbView setTag:THUMBVIEW_OFFSET+i];
[thumbView setDelegate:self];
[thumbView setImageName:name];
CGRect frame = [thumbView frame];
frame.origin.y = THUMB_V_PADDING;
frame.origin.x = xPosition;
frame.size.width = frame.size.width+30;
frame.size.height = frame.size.height+40;
[thumbView setFrame:frame];
[thumbScrollView addSubview:thumbView];
UILabel *pageIndexLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPosition, frame.origin.y+frame.size.height-THUMB_LABEL_HEIGHT, frame.size.width, THUMB_LABEL_HEIGHT)];
[pageIndexLabel setBackgroundColor:[UIColor clearColor]];
[pageIndexLabel setText:[NSString stringWithFormat:#"%d",(i+1)]];
[pageIndexLabel setTextColor:[UIColor whiteColor]];
[pageIndexLabel setTextAlignment:UITextAlignmentCenter];
[thumbScrollView addSubview:pageIndexLabel];
xPosition += (frame.size.width + THUMB_H_PADDING);
}
thumbScrollView.showsHorizontalScrollIndicator = NO;
[thumbScrollView setContentSize:CGSizeMake(xPosition, scrollViewHeight)];
}
}
- (void)downloadPages
{
DownloadOperation *op = [[DownloadOperation alloc] initWithMagazine:magazine];
op.delegate = self;
[[(AppDelegate *)[[UIApplication sharedApplication] delegate] sharedOperationQueue] addOperation:op];
}
- (void)downloadOperation:(DownloadOperation *)operation finishedAtIndex:(NSUInteger)index
{
if (thumbScrollView){
[thumbScrollView viewWithTag:THUMBVIEW_OFFSET+index].alpha = 1.0;
}
}
In DownloadOperation.m
- (void)main
{
// ...
NSUInteger index = 0;
for (Page *page in mMagazine.pages)
{
if (/*page doesn't exist*/){
// download the page;
if ([delegate respondsToSelector:#selector(downloadOperation:finishedAtIndex:)]) {
[delegate downloadOperation:self finishedAtIndex:index];
}
}
index++;
}
}
you're using operation queue to download images -> thus, your finish callbacks might arrive not on the main thread, but you are trying to update you UI anyway - try wrapping your UI interaction into dispatch_async on main thread:
dispatch_async(dispatch_get_main_queue), ^{
if (thumbScrollView){
[thumbScrollView viewWithTag:THUMBVIEW_OFFSET+index].alpha = 1.0;
}
});
Thanks to #Inafziger for clues on this.