How to display page scrubber with QLPreviewController in a subview - ios

I am embedding a QLPreviewController in my own view controller by adding it as a child view controller like this (contentArea is a UIView property that determines which part of the screen the preview should use):
QLPreviewController* preview = [[QLPreviewController alloc] init];
preview.dataSource = self;
preview.delegate = self;
[self addChildViewController:preview];
CGFloat w = self.contentArea.frame.size.width;
CGFloat h = self.contentArea.frame.size.height;
preview.view.frame = CGRectMake(0, 0,w, h);
[self.contentArea addSubview:preview.view];
[preview didMoveToParentViewController:self];
self.qlPreviewController = preview;
This works so far. However, when I open a PDF, I do not get the page scrubber that is shown on the right side when the QLPreviewController is shown full screen (see screenshot).
Using DCIntrospect I see that there is a special subview of type QLScrubView responsible for this:
...
| <QLScrubView: 0x1274e990; frame = (963 64; 61 704); autoresize = LM+H; layer = <CALayer: 0x1274eb30>>
| | <QLThumbnailView: 0x11fc6460; frame = (17 329; 32 45); layer = <CALayer: 0x11fcb4b0>>
| | <QLThumbnailView: 0x11fd45a0; frame = (17 382; 32 45); layer = <CALayer: 0x11fbe830>>
| | <QLThumbnailView: 0x1274dae0; frame = (9 268; 48 61); layer = <CALayer: 0x1273b860>>
...
However, this scrub view is missing in the embedded use case.
Any ideas how to make this appear?

It displays automatically when you have more than one page. I would guess that there's something wrong with your PDF. Try other PDFs from other sources and see if you get the same problem. I use PDFs all the time and the scrubber shows up just fine.
My other thought is maybe resizing your preview controller is not behaving properly. Try loading the preview controller as a modal view controller (no parent) and see if the scrubber is still hidden.

Related

Media Items in JSQMessageViewController's Collection cells are not showing in IOS 14

I am using JSQMessageViewController and I am facing the issue (only in ios14) that i cant see media items like Images, Video and Audio in device though these views are generating debug view hierarchy. See below attached image:-
debug view hierarchy screenshot:
here is the description of UIImage inside collection view cell:
<UIImageView: 0x7fe7d6d95b30; frame = (20 8; 177 131); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x600001ce4ec0>>
here is the screenshot attached of screen:
You can see the view has generated space for image, but its not showing up!
Is anyone facing this issue? how can i solve this problem. This issue is occurring in iOS 14, it works perfectly in iOS 13.
You need to overwrite in JSQMessagesMediaViewBubbleImageMasker.m
method - (void)jsq_maskView:(UIView *)view withImage:(UIImage *)image and change line:
view.layer.mask = imageViewMask.layer;
to be
view.maskView = imageViewMask;
I suggest you to use category for that. For me that was solution.
I would like to suggest to change like as follows along with the Vladimir answer for backward compatibility:
if (#available(iOS 14.0, *)) {
view.maskView = imageViewMask;
} else {
view.layer.mask = imageViewMask.layer;
}

iOS Extension does not display image in UIImageView

I found this good link how to get selected images.
I am trying to set image that I get from extension context to image view that I placed in storyboard.
this my print out code po self.theImageView:
<UIImageView: 0x7b8a1c90; frame = (240 89; 52 41); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7b887fa0>> - (null)
and this is po self.theImageView.image
<UIImage: 0x7a6977f0>
So I even can see image using eye tool when debug it:
But on the screen of my simulator there is no visible image.

Autolayout and UIPopoverController

I created a panel with some subviews in it and used a NSLayoutConstraints to achieve positioning.
I would then display it in a UIPopoverController. Before setting it, I would call [UIView layoutIfNeeded] command to force it to size itself (the overall size is based on the size of an image in it that can be different sizes).
PhotoDisplayPanel *panel = [[PhotoDisplayPanel alloc] initWithPhoto:cell.photo isAddPhoto:cell.isAddPhoto];
DLog(#"BEFORE | panel.frame: %#", panel);
[self.view addSubview:panel];
DLog(#"MIDDLE | panel.frame: %#", panel);
[panel layoutIfNeeded];
DLog(#"AFTER | panel.frame: %#", panel);
log:
DEBUG | -[LoginViewController viewDidLoad] | BEFORE | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (0 0; 0 0); layer = <CALayer: 0x7878a7e0>>
DEBUG | -[LoginViewController viewDidLoad] | MIDDLE | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (0 0; 0 0); layer = <CALayer: 0x7878a7e0>>
DEBUG | -[LoginViewController viewDidLoad] | AFTER | panel.frame: <PhotoDisplayPanel: 0x7878a3f0; frame = (-358 -245; 578 289); layer = <CALayer: 0x7878a7e0>>
Previously, I would add the [panel layoutIfNeeded] call before adding it to a view. This worked fine. But with iOS 8.1, they changed how layoutIfNeeded works and if you call it before adding my panel to a view, it freaks out and starts breaking constraints to make it work properly.
My issue is that working with a UIPopoverController, since I can not call layoutIfNeeded my panel has no size, so it uses the popover's default size:
While the panel looks like:
I create the UIPopoverController, set the panel as its view, and then set the preferedContentSize property to the panel's size:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view = self.currentPanel;
viewController.preferredContentSize = CGSizeMake(self.currentPanel.frame.size.width, self.currentPanel.frame.size.height + 00);
Since the panel has not been sized, it is (0, 0).
My question is now, how can I force my panel to size itself based on the constraints?
The solution is to calculate the preferredContentSize based on your constraints.
Note : Your constraints have to be pinned (left/top/right/bottom) to the view controller view in order to be able to calculate the total width/height of the view.
The way to do it, add these lines in your viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGSize resultSize = [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
self.preferredContentSize = resultSize;
}
Swift version 4/5 of Tanguy G.'s working answer:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let resultSize = view.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
self.preferredContentSize = resultSize
}

.xib not loading properly on iOS 4.3, fine on 5.0?

I'm running into a tricky glitch.
I've got a .xib, which was created by XCode when I created a new UIViewController subclass. It has quite a few elements, including some UIButtons, a bunch of UILabels, a small UIView with some other views inside it, and a UIImageView containing a mostly-transparent image.
In viewDidLoad, I set the background color of the UIImageView to a color using a pattern image.
When I display this view controller in the simulator or on my iPhone 4 (both running iOS 5.1), everything goes smoothly; the patterned background displays, all the interactions work, and so on.
When I test on iOS 4.3, however (either in the simulator or on my iPod Touch 2G), it appears that everything I'm trying to manipulate based on an outlet (e.g. [self.myBackgroundImageView setBackgroundColor...] or [self.mySegmentedControl setEnabled:NO]) just doesn't work at all.
The only even vaguely unusual thing I'm doing when the view gets presented is this, which makes it size properly in a popover:
- (void) viewWillAppear:(BOOL)animated {
CGSize size = CGSizeMake(320, 480); // size of view in popover
self.contentSizeForViewInPopover = size;
[super viewWillAppear:animated];
}
I really can't think of anything else that might be the problem. I've cleaned, rebuilt, all that stuff. Still no dice.
Has anyone else encountered this?
UPDATE per request by ott:
Added the following at the end of -viewDidLoad:
NSLog(#"self.myBackgroundImageView = %# | %#", [self.myBackgroundImageView description], [[self.myBackgroundImageView backgroundColor] description]);
...The output is:
self.myBackgroundImageView = <UIImageView: 0x6d48c80; frame = (0 0; 320 480); autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x6d48b60>> | <UIImageView: 0x5f459b0; frame = (0 0; 320 480); autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x5f45890>> // kCGColorSpaceModelPattern 1
So... not nil. Not sure what the story is here.
UPDATE 2:
It appears the disabling of a UISegmentedControl in iOS 4.3 doesn't dim its display, so that's what that part was about. As for the background pattern image: I can't find confirmation of this, but I'm starting to think it's a bug in iOS 4 that makes a background color using a pattern-image UIColor not display properly on a UIImageView. It works fine if I make the UIImageView have a clear background and put the pattern image UIColor as the background of the main view instead. If anyone comes up with a workaround, or confirmation that this is indeed an iOS 4 bug, it would be much appreciated.

Strange Table View Header issue when using Three20 TTTableViewController

I am building a TTTableViewController subclass based on Three20 TTCatalog sample. In there they have defined a subclass of TTTableViewController which has search functionality, called SearchTextController, and it has a search bar appear in the table view header.
Here's what their loadView method looks like:
- (void)loadView {
[super loadView];
TTTableViewController* searchController = [[[TTTableViewController alloc] init] autorelease];
searchController.dataSource = [[[MockSearchDataSource alloc] initWithDuration:1.5] autorelease];
self.searchViewController = searchController;
self.tableView.tableHeaderView = _searchController.searchBar;
}
I tried to re implement the same kind of functionality in my own subclass of TTTableView. The problem is that I cannot get the search bar to appear.
Running these in loadView of TTCatalog SearchTestController (after the last line)
NSLog(#"_searchController.searchBar address %#",_searchController.searchBar.description);
NSLog(#"self.tableView.tableHeaderView address %#",self.tableView.tableHeaderView.description);
yields the same memory address for the layer (meaning the view got set correctly)
2012-07-03 12:00:02.326 TTCatalog[53493:f803] _searchController.searchBar address <UISearchBar: 0x6a5c940; frame = (0 0; 320 44); layer = <CALayer: 0x6a5ca40>>
2012-07-03 12:00:02.327 TTCatalog[53493:f803] self.tableView.tableHeaderView address <UISearchBar: 0x6a5c940; frame = (0 0; 320 44); layer = <CALayer: 0x6a5ca40>>
When I run the same NSLogs in my app, I get this:
2012-07-03 11:41:54.900 myApp[51991:f803] _searchController.searchBar address <UISearchBar: 0x6a43c20; frame = (0 0; 320 44); layer = <CALayer: 0x6a43ce0>>
2012-07-03 11:41:54.901 myApp[51991:f803] self.tableView.tableHeaderView address <UISearchBar: 0x6a43c20; frame = (0 0; 320 44); layer = <CALayer: 0x6a43ce0>>
The layers have the same memory address in my app as well, but the search bar is not visible in the table view header. Is there something else I am missing here?

Resources