Resets View when dismissing from JTSImageViewController - ios

I have a UITableView with images. When i scroll down and select an image, Onclick of image i am using following library to make it zoomIn/ZoomOut/Panning etc. When i come back, the tableview again scroll back starting at 0 element. I am not using didSelectRow but a custom selector. Has anyone worked with this library before? I can post the code if required.
https://github.com/jaredsinclair/JTSImageViewController
Assigning Selector
AsyncImageView *imageView = [[AsyncImageView alloc] initWithFrame:CGRectMake(10.0f, 0.0f, 300.0f, 300.0f)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[imageView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] init];
[tapRecognizer addTarget:self action:#selector(bigButtonTapped:)];
[imageView addGestureRecognizer:tapRecognizer];
Method Call
- (void)bigButtonTapped:(id)sender {
UIView *view = [sender view];
AsyncImageView *imageView1 = (AsyncImageView *)[view viewWithTag:IMAGE_VIEW_TAG];
// Create image info
JTSImageInfo *imageInfo = [[JTSImageInfo alloc] init];
#if TRY_AN_ANIMATED_GIF == 1
#else
imageInfo.image = imageView1.image;
#endif
imageInfo.referenceRect = imageView1.frame;
imageInfo.referenceView = imageView1.superview;
imageInfo.referenceContentMode = imageView1.contentMode;
imageInfo.referenceCornerRadius = imageView1.layer.cornerRadius;
// Setup view controller
JTSImageViewController *imageViewer = [[JTSImageViewController alloc]
initWithImageInfo:imageInfo
mode:JTSImageViewControllerMode_Image
backgroundStyle:JTSImageViewControllerBackgroundOption_Blurred];
// Present the view controller.
[imageViewer showFromViewController:self transition:JTSImageViewControllerTransition_FromOriginalPosition];
}

It seems JSTImageViewController doesnt play nice with UITableView in iOS8. This issue has been reported in the GitHub page for JSTImageViewController. There's also a possible workaround mentioned :
...Apparently it's the default behaviour to reset the contentOffset after returning from a modal view controller...
...setting the modal presentation style of JTSImageViewController to UIModalPresentationOverFullScreen fixes the issue (since it doesn't remove the hierarchy below it and retains the scroll position I think).
if ([[[UIDevice currentDevice] systemVersion] compare:#"8.0" options:NSNumericSearch] != NSOrderedAscending)
{
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
}
Read the full thread Here

Related

How Do I Load or Update a View From NSObject Class After Getting the Data?

I'm having a bit of trouble updating my UIImageView to contain subviews of buttons after I'm getting the CGPoint data from another class.
In my main VC, I've got an ImageView set as a subview to a UIScrollView that is a subview of the main ViewControllers view.
In viewDidLoad, I'm calling a method from an NSObject class to get the data for all the button locations from my database:
- (void)parseCoordinateData:(NSArray*)data {
NSLog(#"Processing Data");
mapVC = [[ViewController alloc]init];
for(NSArray *table in data) {
NSLog(#"Table: %#", table);
float xValue = [[NSString stringWithFormat:#"%#", [table[0]objectForKey:#"LocationX"]] floatValue];
float yValue = [[NSString stringWithFormat:#"%#", [table[0]objectForKey:#"LocationY"]] floatValue];
NSLog(#"Coordinates: (%f,%f)", xValue, yValue);
CGPoint buttonCoordinate = CGPointMake(xValue, yValue);
[mapVC placeButtonsFromDatabaseWithCoordinates:buttonCoordinate];
}
}
And in the method from the main VC where I'm placing the buttons:
- (void)placeButtonsFromDatabaseWithCoordinates:(CGPoint)point {
NSLog(#"Placing Button at point: %#", NSStringFromCGPoint(point));
UIButton *button = [[UIButton alloc] init];
[self.imageView addSubview:button];
button.frame = (CGRect){.origin = point, .size = CGSizeMake(20.0, 20.0)};
button.backgroundColor = [UIColor greenColor];
button.layer.cornerRadius = 10;
button.clipsToBounds = YES;
button.userInteractionEnabled = YES;
[self animateButton:button];
[self.imageView bringSubviewToFront:button];
}
But the buttons are not appearing on the image view.
Any idea how to get this to work?
EDIT
I've created a very small project to try and replicate this problem. I've created a view controller that calls to an NSObject class that will call back to the View Controller to draw a subview. I am getting an EXC BAD ACCESS error when attempting this.
However, if handling the call explicitly in the main thread, the app will not crash but the view will not draw.
I think this is what's happening when trying to add the button to the image as a subview.
Change
UIButton *button = [[UIButton alloc] init];
to
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

Method doesn't display UIImageView (iOS XCode Cocoa touch)

I'd like to have a method display an image. My view controller calls the method:
eduPopup *thisEduPopup = [[eduPopup alloc] init];
[thisEduPopup displayPopup];
In the method I have:
-(void) displayPopup {
UIImageView *thisImage = [[UIImageView alloc] init];
thisImage.image = [UIImage imageNamed:#"referral_eduscreen_text_solid.png"];
thisImage.frame = CGRectMake(0, 0, thisImage.image.size.width, thisImage.image.size.height);
[self.superview addSubview:thisImage];
}
...but I get nothing. Is self.superview the right reference? What I should be putting there?

Image view not responding to touch event

I have a grid of thumbnail images, and when one of them is touched, I'd like to show the whole image. Now, I know that UIImageView does not respond to touch events, but as suggested in this answer, I created a UIButton to handle the event. See code below:
- (void)displayImage
{
NSUInteger i = 0; // The actual code is different and works; this is just for brevity's sake.
// UILazyImageView is a subclass of UIImageView
UILazyImageView *imageView = [[UILazyImageView alloc] initWithURL:[NSURL URLWithString:[[[self images] objectAtIndex:i] thumbnailUrl]]];
UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[imageButton setFrame:[imageView frame]];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
[[self containerView] addSubview:imageView];
[imageView release];
}
}
- (void)imageTapped:(id)sender
{
NSLog(#"Image tapped.");
// Get the index of sender in the images array
NSUInteger index = 0; // Don't worry, I know. I'll implement this later
FullImageViewController *fullImageViewController = [[[FullImageViewController alloc] initWithImageURL:[NSURL URLWithString:[[[self images] objectAtIndex:index] url]]] autorelease];
[[self navigationController] pushViewController:fullImageViewController animated:YES];
}
Ok. So I've create a custom button, set its frame to match the image frame, told it to respond to touch up inside and how to respond, and added it to the image's subviews. But when I run this, I get nothing. The "Image tapped." doesn't appear in the console, so I know that the message isn't being sent. What am I doing wrong here?
Many thanks for all your help.
by default UIImageView has its userInteractionEnabled property set to NO
add this line
imageView.userInteractionEnabled = YES;
Try
imageView.userInteractionEnabled = YES;
This is a property inherited from UIView, but as per Apple's docs, UIImageView changes its default value to NO, ignoring all events.
In addition to setting imageView.userInteractionEnabled = YES, you can eliminate the button altogether and add a UITapGestureRecognizer to the UIImageView to handle taps. It would look something like:
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
[imageView addGestureRecognizer:recognizer];

Adding the scrollview created by photoscroller to a subview

I'm trying to modify Apple's PhotoScroller example to make the scrollview that is created into a subview instead of it being a view that takes up the entire screen. Any ideas on how this can be accomplished?
- (void)loadView
{
// Step 1: make the outer paging scroll view
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
pagingScrollView.pagingEnabled = YES;
pagingScrollView.backgroundColor = [UIColor blackColor];
pagingScrollView.showsVerticalScrollIndicator = NO;
pagingScrollView.showsHorizontalScrollIndicator = NO;
pagingScrollView.contentSize = [self contentSizeForPagingScrollView];
pagingScrollView.delegate = self;
// When I do this it fails
[self.view addSubview:pagingScrollView];
// Step 2: prepare to tile content
recycledPages = [[NSMutableSet alloc] init];
visiblePages = [[NSMutableSet alloc] init];
[self tilePages];
}
You just need to modify the frame of the scrollview to be positioned and sized how you want:
This is the line in the view controller that sets it up in the example
pagingScrollView = [[UIScrollView alloc] initWithFrame:pagingScrollViewFrame];
As an example here is a sample frame with some hardcoded values:
CGRect scrollFrame = CGRectMake(100,100,100,100);
pagingScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
So, I found out that I was able to add the scrollView as a subview by changing the method from loadView to viewDidLoad.
I have no clue why that works, but it does. I'd love to know why that's the case however...

IOS - External (hdmi) output fills only half the screen except when coding view manually

So, as the title says, I have an hdmi out on the iPad and an observer registered for screen connections, upon connection the user chooses the res and a view is outputted.
However, if I load a view from a nib, or even from a programatic view controller, the ipad shows a landscape view in portrait (yes, both situations are set to landscape).
I.e.
ExternalViewController *ex = [[ExternalViewController alloc] init];
[externalWindow setRootViewController:ex];
does this:
If I create the view itself programatically. like so:
UIView *test = [[UIView alloc] initWithFrame:[externalScreen applicationFrame]];
[test setBackgroundColor:[UIColor whiteColor]];
UILabel *msgLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 100, 30)];
msgLabel.text = #"External!";
[test addSubview:msgLabel];
It runs like some form of magical dream:
However I want the viewcontroller to load (and work!) so, StackOverflow, I ask you. has anyone come across this before?
EDIT: It does go without saying that common sensical answers do not get a bounty, I am after a fix, not a workaround. With my limited brain, all I can think to do is create a method that creates a view based on it's inputs and adds that as a subview of the external monitor, it is clear that this is a hack solution so a fix is appreciated! Thanks!
EDIT:
-(id)initWithFrame:(CGRect)_rect
{
rect = _rect;
if (self = [super init])
{
externalView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"105.png"]];
externalView.alpha = 0.0;
[externalView setFrame:rect];
[externalView setBackgroundColor:[UIColor yellowColor]];
self.view = [[UIView alloc] initWithFrame:rect];
self.view.backgroundColor = [UIColor whiteColor];
return self;
}
}
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:rect];
self.view.backgroundColor = [UIColor blackColor];
[self.view addSubview:externalView];
}
As requested, this is how I am loading the viewcontroller, initialising with the size of the external screen. Thanks
Just return NO in - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation in your UIViewController subclass.
// ugly, don't use this in real code
if ([UIScreen screens].count == 1) return; // just one screen, eww.
// getting the secondary screen
UIScreen *screen = [[UIScreen screens] objectAtIndex:1];
__block UIScreenMode *highestWidthMode = NULL;
[screen.availableModes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UIScreenMode *currentModeInLoop = obj;
if (!highestWidthMode || currentModeInLoop.size.width > highestWidthMode.size.width)
highestWidthMode = currentModeInLoop;
}];
// setting to the highest resolution available
screen.currentMode = highestWidthMode;
NSLog(#"screen.currentMode = %#", screen.currentMode);
screen.overscanCompensation = UIScreenOverscanCompensationScale;
// initializing screen
secondWindow = [[UIWindow alloc] initWithFrame:[screen bounds]];
[secondWindow setScreen:screen];
// other view is a UIViewController, just remember to return NO in - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation or the iOS will rotate the frame.
UIViewController *vc = [[OtherView alloc] initWithNibName:#"OtherView" bundle:nil];
secondWindow.rootViewController = vc;
[secondWindow makeKeyAndVisible];

Resources