webview overlaps with status bar only on first load - ios

The status bar overlaps with the top of my webview, exactly how it looks in this post.
However my situation is different from his, because the overlap is only present at the very first load of the webivew, before any of these things happen:
Things that will make the webview spaced properly:
I switch away from the tab of the webview, and switch back
I press any of the js buttons on the page
I rotate the device
Example vid of 1 and 2 on the list
In the video, it starts with showing wikipedia improperly spaced, but once I press the sidebar button, it fixes the spacing. Then I scroll to stackoverflow.com, it is improperly spaced, but when I scroll away and come back it fixes itself.
I have all of my webviews constrained with Webview.top = Top Layout Guide.bottom
It happens with classes as simple as this:
class testweb: UIViewController {
#IBOutlet weak var webview: UIWebView!
override func viewDidLoad() {
let url = NSURL (string: "https://stackoverflow.com")
let requestObj = NSURLRequest(URL: url!)
webview.loadRequest(requestObj)
}
}
It happened before I added the animation.
It happens in the simulator, on a real device, and on both iOS 8 and 9
Any ideas?

Related

UISheetPresentationController displaying differently on different phones

I created a UIStoryboardSegue to make a "Bottom Sheet segue". Our designer shared a screenshot of the app on his phone and the bottom sheet is displaying differently, despite the fact we are both on the same iOS version.
On mine and my simulator, when the bottom sheet opens, it lightens the source view and then shrinks it down a little, so it appears just barely behind the bottom sheet
On the same screen on the designers device, it dims the background and leaves the source view full size, showing the top of the buttons in the navigation bar
I've noticed the Apple maps bottom sheet behaves like the designers, no shrinking of the background view. But I can't see any settings that would affect this. How can I stop the sheet from resizing the source view on mine and function like it's supposed to?
Here's my code:
import UIKit
public class BottomSheetLargeSegue: UIStoryboardSegue {
override public func perform() {
guard let dest = destination.presentationController as? UISheetPresentationController else {
return
}
dest.detents = [.large()]
dest.prefersGrabberVisible = true
dest.preferredCornerRadius = 30
source.present(destination, animated: true)
}
}
Found a hack to force it to never minimise the source view at least, not really what I wanted, but keeps it consistent. Supposedly, .large() is always supposed to minimize the source view, you can avoid this in iOS 16 by creating a custom detent that is just a tiny bit smaller than large like so:
let customId = UISheetPresentationController.Detent.Identifier("large-minus-background-effect")
let customDetent = UISheetPresentationController.Detent.custom(identifier: customId) { context in
return context.maximumDetentValue - 0.1
}
dest.detents = [customDetent]
And as a bonus, found a way to control the dimming on the bottom sheet overlay. There is a containerView property on the presentationController, but it is nil when trying to access it in while in the segue. If you force code to run on the main thread, after the call to present, you can access the containerView and set your own color / color animation
e.g.
...
...
source.present(destination, animated: true)
DispatchQueue.main.async {
dest.containerView?.backgroundColor = .white
}

Subtitle Above Large Nav Bar Title

I was wondering how we could get the subtitle (like a date) above the navbar title when using the prefersLargeTitles feature. Something like the music app. I would also like the large button beside it (like the profile button in the music app). I would still like the large title to animate to the top and become small when the screen is scrolled (like the browse page on the music app).
The code I am using so far is
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.prefersLargeTitles = true
collectionView.initialize()
self.title = "Home Screen"
}

Adding overlay buttons to tvOS AVPlayerViewController

I'm trying to build an overlay that appears over an AVPlayer when I press pause. The problem I'm having is that while I can overlay buttons just fine I can't get the focus engine in tvOS to focus on them... I'm pretty sure this is happening as the player frame robs focus (it's fullscreen # 1080p) and I can't focus on objects that are inside of its frame.
Pseudo code for what I'm doing:
class MyViewController: UIViewController {
var playerController = AVPlayerViewController()
#IBOutlet weak var button: UIButton! // button centred on screen that requires focus
override func viewDidLoad() {
super.viewDidLoad()
self.playerController.player = AVPlayer(url: myURL)
self.playerController.view.frame = self.view.bounds
self.view.addSubview(self.playerController.view)
self.view.bringSubview(toFront: self.button)
}
// ... functions that enable listeners and show/hide button when self.playerController.player rate changes
}
What I want is to be able to press pause, then swipe up to get focus on the button(s) instead of the seek bar and then swipe back down to the seek bar if needed. Much like the Apple Music application that comes with the tvOS.
Thanks.
You can set desired custom vc with action items to var customOverlayViewController: UIViewController? { get set } of your AVPlayerViewController instance.
(available from tvOS 13)
Official documentation states:
When the transport bar is hidden, the player view controller presents
the overlay view controller’s view when a user swipes up on the Siri
Remote during playback. Use this property to set a custom view
controller instead of installing your own swipe gesture recognizer.
https://developer.apple.com/documentation/avkit/avplayerviewcontroller/3229856-customoverlayviewcontroller
You can also check this video starting from 26:07 to see it in action.
https://developer.apple.com/videos/play/wwdc2019/503
P.S. Don't use var contentOverlayView: UIView? { get } to display interactable content, as official documentation states:
Use the content overlay view to add noninteractive custom views, such
as a logo or watermark, between the video content and the controls.
https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615835-contentoverlayview
My solution is to override preferredFocusEnvironment and add some listeners to the parent VC to change a condition when certain actions are taken...not perfect but good enough.
override var preferredFocusEnvironment {
if self.someCondition {
return [self.button]
}
else {
return [self.playerController.view]
}
}

How to resize a Maxpreps HTML widget to fit the UIWebView?

I am trying to use the Maxpreps widget (http://www.maxpreps.com/widgets/createwidget.aspx) in my app to show school sports updates.
I made a html file in xcode and pasted the code provided from Maxpreps. I created a webview and used the code on the view controller.
#IBOutlet weak var sportsTest: UIWebView!
sportsTest,loadRequest(NSURLRequest(URL: NSURL(fileURLWWithPath: NSBundle.mainBundle().pathForResource("widgetcode", ofType: "html")!)))
The problem is when the code is being shown it wont fit the UIWebView properly.
The issue you are having with the HTML not fitting in the UIWebView is not simple to resolve, but I can give you a hack that will get your content on the screen.
The problem is that the web page from Maxpreps loaded from the URL in their widget isn't designed to fit completely on an iPhone in portrait orientation. However it is a responsive HTML page so that is the good news.
First, you don't need to load the script tag or write an HTML file since all that gives you is a link that you need to click, right? You don't want that link, you want the content of what is behind the link, right? Hopefully!
This view controller implementation should work fine:
import UIKit
class ViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// This will force the UIWebView to downscale and fit your page, but
// it is hacky because 91% of original size might not always be the
// right amount. This is why I said it is hard.
self.webView.scrollView.minimumZoomScale = 0.3
self.webView.scrollView.maximumZoomScale = 2.0
self.webView.scrollView.setZoomScale(0.91, animated: false)
}
override func viewWillAppear(animated: Bool) {
if let url = NSURL(string: "http://www.maxpreps.com/local/team/home.aspx?gendersport=boys,baseball&schoolid=45823724-55bc-4d89-926b-b1974b3d8e36") {
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}
else {
println("Failed to create URL")
}
}
}
The above works, but better solutions IMHO would be to:
1) Ask Maxpreps to fix their responsive HTML page so that it renders on an iPhone in portrait orientation
2) Ditch HTML altogether and query the information you need using a REST API if they make one available, and then write a native non-HTML screen
3) Attempt to get a dynamic scaling solution in place that works. These are prone to failure based on my experience
Here is what I see on my simulator when I run it:
Another example:

How do i implement the Search button on Xcode 6

I'm quite new to Xcode. I'm building a basic app that searches a website. Ive got the search button to work with a Go button at the side. How would i make the search button also respond to the search on the bottom right on the keyboard?
#IBAction func didClickGo(AnyObject) {
var text = textField.text
var url = NSURL.URLWithString("http://www.mysite.co.uk/search?controller=search&orderby=position&orderway=desc&search_query="+text)
var request = NSURLRequest(URL: url)
webView.loadRequest(request)
Check out this answer:
https://stackoverflow.com/a/22178145/4014757
First, in your view controller you can assign a delegate for the search bar (probably also your view controller)
searchBar.delegate = this;
Then in your view controller (the delegate), you can override the searchBarSearchButtonClicked method with whatever you want to do when the search button is pressed.
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Hope this is what you're looking for, good luck.

Resources