When loading the PDF in a QLPreviewController, it does not fit the content that I have inside, I am adding it as a subview to a container view. The PDF has a greater zoom than required. Is there any way to modify the zoom of QLPreview?
let preview = QLPreviewController()
preview.dataSource = self
preview.navigationController?.isNavigationBarHidden = true
addChild(preview)
termsConditionsContainer.addSubview(preview.view)
termsConditionsContainer.backgroundColor = .white
preview.view.translatesAutoresizingMaskIntoConstraints = false
preview.view.topAnchor.constraint(equalTo: termsConditionsContainer.topAnchor).isActive = true
preview.view.leftAnchor.constraint(equalTo: self.termsConditionsContainer.leftAnchor).isActive = true
preview.view.widthAnchor.constraint(equalTo: self.termsConditionsContainer.widthAnchor).isActive = true
preview.view.bottomAnchor.constraint(equalTo: termsConditionsContainer.bottomAnchor).isActive = true
preview.didMove(toParent: self)
Related
How does one disable scroll bounce in a PDFView using PDFKit?
The view where the PDF is shown doesn't have a scroll bounce option.
Here's my code:
if let path = Bundle.main.path(forResource: pdfObject, ofType: "pdf") {
let url = URL(fileURLWithPath: path)
if let pdfDocument = PDFDocument(url: url) {
pdfView.autoresizesSubviews = true
pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight,
.flexibleTopMargin, .flexibleLeftMargin]
pdfView.autoScales = true
pdfView.displaysPageBreaks = true
pdfView.displayDirection = .vertical
pdfView.displayMode = .singlePageContinuous
pdfView.document = pdfDocument
pdfView.maxScaleFactor = 4.0
pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit
}
}
Thanks in advance (for what is likely a ridiculously simple question!)
Unfortunately, there isn't an exported API to set the PDFView desired bouncing behavior.
Having said that, you can (safely) exploit a PDFView implementation detail to hack your way around it for now:
extension PDFView {
/// Disables the PDFView default bouncing behavior.
func disableBouncing() {
for subview in subviews {
if let scrollView = subview as? UIScrollView {
scrollView.bounces = false
return
}
}
print("PDFView.disableBouncing: FAILED!")
}
}
and then use it like this in your code:
pdfView.disableBouncing()
Caveat. Please keep in mind that such solution might break in future iOS releases. Nevertheless, rest assured your app won't crash as a result (you only won't be disabling the bouncing behavior at all).
func configureSearchController()
{
resultsController.tableView.delegate = self
resultsController.tableView.dataSource = self
self.searchController = UISearchController(searchResultsController: self.resultsController)
//self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
self.searchController.searchBar.sizeToFit()
searchController.searchBar.delegate = self
self.searchController.searchBar.scopeButtonTitles = []
for subView in searchController.searchBar.subviews {
for subViewOne in subView.subviews {
if subViewOne is UITextField {
searchTextField = subViewOne as! UITextField
subViewOne.backgroundColor = UIColor.white
var currentTextFieldBounds = subViewOne.bounds
currentTextFieldBounds.size.height = 45
subViewOne.bounds = currentTextFieldBounds
break
}
}
}
extendedLayoutIncludesOpaqueBars = true
definesPresentationContext = true
}
This doesn't change height of text field unexpectedly. I also want to change height of search bar. What changes should I make here for the same to work?
IMO, The search bar size shouldn't be changed as it's the native standard provided by Apple. Also the way you use of recursively searching of textfield is not recommended and not guaranteed to work in all iOS versions.
Maybe you can try to use custom Search bar with your own text field and u can easily play with it.
I am creating custom node to show gif file with play and pause button.
Following is my code.
import Foundation
import AsyncDisplayKit
class GifNode: ASCellNode {
var gifImageNode:ASNetworkImageNode = {
let node = ASNetworkImageNode()
node.contentMode = .scaleAspectFit
node.shouldRenderProgressImages = true
return node
}()
var playImage: ASImageNode = {
let node = ASImageNode()
node.contentMode = .scaleAspectFit
node.style.height = ASDimensionMakeWithPoints(30)
node.style.height = ASDimensionMakeWithPoints(30)
node.backgroundColor = .gray
node.image = #imageLiteral(resourceName: "play")
return node
}()
init(model:GifContent)
{
super.init()
self.automaticallyManagesSubnodes = true
let width = UIScreen.main.bounds.size.width
let height = (width * model.height) / model.width
gifImageNode.url = URL(string: "https://i.pinimg.com/originals/07/44/38/074438e7c75034df2dcf37ba1057803e.gif")
gifImageNode.style.width = ASDimensionMake(width)
gifImageNode.style.height = ASDimensionMake(height)
gifImageNode.animatedImagePaused = true
gifImageNode.addTarget(self, action: #selector(self.toggleGifPlay), forControlEvents: .touchUpInside)
}
#objc func toggleGifPlay()
{
self.gifImageNode.animatedImagePaused = !self.gifImageNode.animatedImagePaused
self.playImage.isHidden = !self.gifImageNode.animatedImagePaused
}
override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
let playButtonCenterSpec = ASCenterLayoutSpec(centeringOptions: .XY, sizingOptions: .minimumXY, child: self.playImage)
return ASOverlayLayoutSpec(child: gifImageNode, overlay: playButtonCenterSpec)
}
}
When I try to use gif node in another ASCellNode it does not render. I can see play button but not the actual gif file. If I try to load jpeg with same control, it works fine. Also it works fine, if I try to load gif directly and not using above class.
Not sure if I am missing anything.
I test your app, but gifImageNode.animatedImagePaused = true is disabled by default ur animation.
I am including a search bar by code and enabling interaction using the code below, the search bar is displayed but when I click on the field editing is not enabled:
let searchTableViewController = storyboard?.instantiateViewController(withIdentifier: "SearchBarTableVC") as? SearchBarTableVC
searchTableViewController?.handleMapSearchDelegate = self
searchTableViewController?.mapView = self.mapView
searchBarController = UISearchController(searchResultsController: searchTableVC)
searchBarController?.searchResultsUpdater = searchTableVC
let searchBar = searchBarController?.searchBar
searchBar?.sizeToFit()
searchBar?.placeholder = "Digite o local"
searchBar?.tintColor = UIColor.red
searchBar!.isUserInteractionEnabled = true
searchBar?.backgroundColor = UIColor(named: "ColorTransparent")
navigationItem.titleView = searchBarController?.searchBar
searchBarController?.hidesNavigationBarDuringPresentation = false
searchBarController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
If you're using iOS 11, the preferred way is simply to write:
navigationItem.searchController = searchController
That's all. You don't have to position the search bar or put it in any view.
I've got one of these Views here:
let placeContainerView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.whiteColor()
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 7
view.layer.masksToBounds = true
return view
}()
And I'm looking to create one next to it every time a function "createNewView()" is called.
let showFullPlaceContainerView = UITapGestureRecognizer(target: self, action: #selector(showFullPlaceContainerViewFunction))
placeContainerView.addGestureRecognizer(showFullPlaceContainerView)
That I want each of the placeContainerView's to respond to.
So I want a view to be generated and I'll give it certain values. And then when I call the function createNewView() I'll get a new view next to it that is exactly the same except with whatever new values I put in.
If you've got any ideas please let me know!
Thank you
EDIT:
The code below demonstrates how I want to setup the placeContainerView each time but I need them to be displayed so that the placeContainerView.topAnchor() is different each time.. How exactly does that work if it is kept in its own class and doesn't know how many times it has been created?
Also, as placeContainerView contains placeLabel and placeImageView do these have to be generated inside the new PlaceContainerViewClass as well?
func setupPlaceContainerView() {
placeContainerView.leftAnchor.constraintEqualToAnchor(view.leftAnchor, constant: -180).active = true
placeContainerView.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 80).active = true
placeContainerView.widthAnchor.constraintEqualToConstant(227).active = true
placeContainerView.heightAnchor.constraintEqualToConstant(45).active = true
placeContainerView.addSubview(placeLabel)
placeContainerView.addSubview(placeImageLabelSeparator)
placeContainerView.addSubview(placeImageView)
placeLabel.leftAnchor.constraintEqualToAnchor(placeContainerView.leftAnchor).active = true
placeLabel.topAnchor.constraintEqualToAnchor(placeContainerView.topAnchor).active = true
placeLabel.widthAnchor.constraintEqualToConstant(180).active = true
placeLabel.heightAnchor.constraintEqualToAnchor(placeContainerView.heightAnchor).active = true
placeImageLabelSeparator.leftAnchor.constraintEqualToAnchor(placeLabel.rightAnchor).active = true
placeImageLabelSeparator.topAnchor.constraintEqualToAnchor(placeContainerView.topAnchor).active = true
placeImageLabelSeparator.widthAnchor.constraintEqualToConstant(2).active = true
placeImageLabelSeparator.heightAnchor.constraintEqualToAnchor(placeContainerView.heightAnchor).active = true
placeImageView.leftAnchor.constraintEqualToAnchor(placeImageLabelSeparator.rightAnchor).active = true
placeImageView.topAnchor.constraintEqualToAnchor(placeContainerView.topAnchor).active = true
placeImageView.widthAnchor.constraintEqualToConstant(45).active = true
placeImageView.heightAnchor.constraintEqualToAnchor(placeContainerView.heightAnchor).active = true
As noted by #Paulw11, this task is simply done by creating a new class.
class placeContainerView:UIView {
var x:Double!
var y:Bool!
var z:UILabel!
var controller:UIViewController!
//If you want to pass specific values number, you can use convenience init method OR you can use the default init method they give you.
//previousLabelFrame:CGrect = CGRect() // I defaulted all these values to 0, make them whatevree u need. You would use the default one for the first Label you would make. Then after that, you would pass in the previous one made, to get the frame of it so you can add to the one after that.
convenience init(x:Double,y:Bool, z:UILabel, previousLabelFrame:CGRect = CGRect(x: 0, y:0, width:0, height:0), VC:UIViewController) {
self.x = x
self.y = y
self.z = z
self.controller = VC
let distance = self.controller.width*0.1 //Whatever u decide here
//You could just do CGRect(x:previousLabelFrame.maxX+distance, depeding on what you need.
self.frame = CGRect(x: previousLabelFrame.minX+distance, y:previousLabelFrame.minY, width: previousLabelFrame.width, height:previousLabelFrame.height)
}
}
Usage inside ViewController:
var views:[placeContainerView] = []
let view:placeContainerView = placeContainerView(10, true, UILabel(),views[views.count-1], self)
self.views.append(view)
//OR if this is the FIRST placeContainerView of the whole app, it will use the default values for the frame.
let view:placeContainerView = placeContainerView(10, true, UILabel(), self)
self.views.append(view)
Some odd example of how to use.
Then everytime they click a button, just make a new placeContainerView