GIFs displayed incorrectly using FLAnimatedImage Library on SWIFT - ios

I am using the FLAnimatedImage Library (downloaded via CocoaPods) to display GIFs in a simple test app. The app is designed to play a GIF just once when a button is pressed. To play the GIF only once I make use of a loopCompletionBlock.
Problem: the FLAnimatedImage routine briefly displays the final frame of the GIF before correctly playing the frames of the GIF. The error takes place regardless of what GIF is displayed so it is a code problem and not a GIF problem. The problem is not caused by the loopCompletionBlock because it still takes place even when I remove that code. Does anyone know how to fix this problem?
I am running Xcode 14.1. and Swift 5.7.
import UIKit
import FLAnimatedImage
class ViewController: UIViewController {
#IBOutlet weak var GIFImageView: FLAnimatedImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func playGIFButtonPressed(_ sender: Any) {
if let path = Bundle.main.path(forResource: "check-mark-verified", ofType: "gif") {
if let data = NSData(contentsOfFile: path) {
let gif = FLAnimatedImage(animatedGIFData: data as Data)
GIFImageView.animatedImage = gif
}
}
self.GIFImageView.loopCompletionBlock = {_ in
self.GIFImageView.stopAnimating()
}
}
}

Related

Can't drag outlets from storyboard to code, but my class is connected properly

So, basically, I've been launching the app with existing .xib VC and Swift file, but i've met a problem: despite all the connections were properly distributed, when launched, app didn't show my VC, it basically showed transparent view(bottom sheet). After checking the fact that I did everything as I should've done, I've tried to re-create things, deleted my old Swift file and storyboard VC and created a new one.
My storyboard VC and Swift VC
As you may see on this image, I've connected everything properly, name of custom class is correct, I have even filled in ID's, despite I don't use it. And even though, dragging my views form .xib to my Swift file does nothing. Then I've tried to manually write the code of #IBOutlet and connected views - it seemed right, but issue remained: app was crushing when I tried to launch this VC. Can't get what my problem is and rescuing some help on this case.
Here is my swift file:
import Foundation
import UIKit
import Alamofire
import AlamofireImage
class MarkerPopUpView: UIViewController {
var id = "254"
func getID(title: String) {
id = title
}
func getImage(title: String) {
var url = String()
for marker in arrOfMarkers {
if (marker.id) == Int(title) {
url = marker.getImage
streetNameView.text = marker.street
}
}
AF.request(url).responseImage { response in
debugPrint(response)
if case .success(let image) = response.result {
self.markerImage.image = image.af.imageRounded(withCornerRadius: 16)
self.markerImage.layer.cornerRadius = 12
print ("Success!")
}
else{
self.markerImage.image = UIImage(named: "Illustration")
self.markerImage.layer.cornerRadius = 12
let error = response.error
print ("ERROR: \(String(describing: error))")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
getImage(title: id)
}
}

Updating Labels on a second View Controller

I have several different ViewControllers set up in my project. The first one acts as a 'landing' page and and on pressing a button the view is directed to a following ViewController.
There are various buttons and labels on there that I want to use to provide information and run a method. The buttons all work ok, but I have followed every tutorial I can to get the labels to update based on a method, and I can't seem to get them to do so.
I know the methods are called correctly as I have put print statements in there to check.
Basic idea is, program plays a series of beeps separated by a delay (bleep_time), this changes each level (bleep_level) and there are several steps (bleep_step) in each level. Ive simplified the arrays containing this data to save space.
I have successfully created a number of tutorial projects and the labels all update correctly, but they only use one ViewController.
Is the issue I am facing due to using 2 ViewControllers?
ViewController 1
import UIKit
class Bleep_Test_Menu: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
View Controller 2
import UIKit
import AVFoundation
class Bleep_Test_Level_1: UIViewController {
// Global Variables
var audioPlayer: AVAudioPlayer?
// Bleep test delays
var bleep_time = [1,2,3,4]
// Levels of bleep test
var bleep_level = [1,2,3,4]
// Level Label
#IBOutlet weak var bleepTestLevel1Level: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// Function to run repeated bleeps
#IBAction func bleepTestLevel1Start(_ sender: Any) {
var i = 0
tracker = false
let length = bleep_time.count
while i < length {
var bleeplevel = bleep_level[i]
bleepTestLevel1Level.text = "\(bleeplevel)"
playSaveSound()
sleep(UInt32(bleep_time[i]))
i += 1
}
}
// Function to play sounds
func playSaveSound(){
let path = Bundle.main.path(forResource: "Sound1.wav", ofType: nil)!
let url = URL(fileURLWithPath: path)
do {
//create your audioPlayer in your parent class as a property
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer?.play()
} catch {
print("couldn't load the file")
}
}
}
The only error I keep getting in the console is this;
"Tests[53616:891478] - changing property contentsGravity in transform-only layer, will have no effect"
But I can't seem to find anything that relates to my issue.

WkWebView how manage events and window launched by input type file

This is my first app to iOS and i do the same app to Android without problems and now i'm stucked to this problem.
When the user click on "choose file" into webview the phone ask me where i want pick the photo (or file), and if i select "Close" the entire WebView get closed!
How can i manage that events? (image below show the windows that take me this problems)
Same problem if i click to a loaded attachment a appear a window that show me the image and if i long press the image some buttons appear (copy, download or close).... if i press one of them the WebView get closed...
The back button is disabled because the user can't use back in this case and must follow the workflow forced by webview.
I try with this code but still close the webview
import UIKit
import WebKit
class MyWebViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
//Variable used for take received data from other ViewControllers
var urlString = String()
var callerString = String()
// MARK: - Properties
#IBOutlet weak var myWebView: WKWebView!
#IBOutlet weak var backButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
if callerString == "CodeController"{
backButton.isEnabled = false
} else {
backButton.isEnabled = true
}
myWebView.navigationDelegate = self
view.addSubview(myWebView)
// Do any additional setup after loading the view.
let url = URL(string: urlString)
myWebView.load(URLRequest(url : url!))
}
#IBAction func backButtonAction(_ sender: Any) {
if callerString != "CodeController"{
if myWebView.canGoBack{
myWebView.goBack()
}else {
//Go to Main View
self.navigationController?.popViewController(animated: true)
self.performSegue(withIdentifier: "backOnViewControllerSegue", sender: self)
}
}
}
Here some images of which buttons close the entire WebView and how manage them in a different way?
It was a bug from WkWebView libraries.
To avoid that just upgrade OSX and XCODE to last versions and the problem is solved.
Not sure if it's solved for all iOS OS but sure for iOS 12, and maybe 10

WKWebView's (beta) takeSnapshot method, how to implement?

I noticed the WKWebView documentation now lists a method called takeSnapshot that is supported by iOS 11 and macOS 10.13 and above (Xcode 9 beta).
Has anyone played around with yet or implemented? I'm trying to get it working in a playground but I'm not sure where to start? Is this a method on a WKWebView?
My code:
import UIKit
import PlaygroundSupport
import WebKit
let frame = CGRect(x: 0, y: 0, width: 800, height:600)
let web = WKWebView(frame: frame)
let rq = URLRequest(url: NSURL(string: "http://apple.com")! as URL)
web.load(rq)
PlaygroundPage.current.liveView = web
PlaygroundPage.current.needsIndefiniteExecution = true
//Take snapshot?
As far as I tested, the method takeSnapshot(with:completionHandler:) actually exists as an instance method and works as expected.
Just that it's a little hard to use it.
The method declares its first parameter as WKSnapshotConfiguration?, but the class WKSnapshotConfiguration is not imported with import WebKit. You can pass nil to the parameter, but to use the method, you need to import the type WKSnapshotConfiguration. And I could not have found any dependent submodules to import WKSnapshotConfiguration.
So, if you want to play with this new feature, you need to create an App project with bridging-header.
(If you know how to use bridging-header in the Playground, you may test this feature in it. But I do not know if you can or how.)
{ProjectName}-Bridging-Header.h:
#import CoreGraphics;
#import <WebKit/WKSnapshotConfiguration.h>
And an example of ViewController.swift:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var webView: WKWebView!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: URL(string: "http://apple.com")!)
webView.load(request)
}
#IBAction func buttonPressed(_ sender: UIButton) {
webView.takeSnapshot(with: nil) {image, error in
if let image = image {
self.imageView.image = image
print("Got snapshot")
} else {
print("Failed taking snapshot: \(error?.localizedDescription ?? "--")")
}
}
}
}
(Place a WKWebView, a UIImageView and a UIButton on a View.)
One more, this seems to be a bug of WebKit framework, you should better send a bug report to Apple.

Open with file in swift

When you open url that contain PDF file safari ask you if you want to open it on safari or in iBook.
I want to do the same thing ,
in my project i had a collection view contains videos and photos,
i want the user to chose if he want to open the file on the app or to open it with other media player.
For loading into your own app it depends on which class you're using to display content on the exact code you'd use but for opening in another app you'd normally use a share button. Here is example code that will work if you wire up the #IBAction and #IBOutlet to the same bar button in your UI (and place a file at the fileURL that you specify):
import UIKit
class ViewController: UIViewController {
// UIDocumentInteractionController instance is a class property
var docController:UIDocumentInteractionController!
#IBOutlet weak var shareButton: UIBarButtonItem!
// called when bar button item is pressed
#IBAction func shareDoc(sender: AnyObject) {
// present UIDocumentInteractionController
if let barButton = sender as? UIBarButtonItem {
docController.presentOptionsMenuFromBarButtonItem(barButton, animated: true)
}
else {
print("Wrong button type, check that it is a UIBarButton")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// retrieve URL to file in main bundle
if let fileURL = NSBundle.mainBundle().URLForResource("MyImage", withExtension: "jpg") {
// Instantiate the interaction controller
self.docController = UIDocumentInteractionController(URL: fileURL)
}
else {
shareButton.enabled = false
print("File missing! Button has been disabled")
}
}
}
Notes
A UIDocumentInteractionController is used to enable the sharing of documents between your app and other apps installed on a user's device. It is simple to set up as long as you remember three rules:
Always make the UIDocumentInteractionController instance a class
(type) property. If you only retain a reference to the controller
for the life of the method that is triggered by the button press
your app will crash.
Configure the UIDocumentInteractionController
before the button calling the method is pressed so that there is not
a wait in which the app is waiting for the popover to appear. This is important because while
the presentation of the controller happens asynchronously, the instantiation does not. And you may find that there is a noticeable delay to open the popover if
you throw all the code for instantiation and presentation inside a
single method called on the press of a button. (When testing you might see a delay anyway because the share button is likely going to be pressed almost straightaway but in real world use there should be more time for the controller to prepare itself and so the possibility of lag is less likely.)
The third rule is that you must test this on a real device not in the simulator.
More can be found in my blogpost on the subject.
Edit: Using a UIActivityViewController
Code for using UIActivityViewController instead of UIDocumentInteractionController
import UIKit
class ViewController: UIViewController {
// UIDocumentInteractionController instance is a class property
var activityController: UIActivityViewController!
#IBOutlet weak var shareButton: UIBarButtonItem!
// called when bar button item is pressed
#IBAction func shareStuff(sender: AnyObject) {
if let barButton = sender as? UIBarButtonItem {
self.presentViewController(activityController, animated: true, completion: nil)
let presCon = activityController.popoverPresentationController
presCon?.barButtonItem = barButton
}
else {
print("not a bar button!")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// retrieve URL to file in main bundle
if let img = UIImage(named:"MyImage.jpg") {
// Instantiate the interaction controller
activityController = UIActivityViewController(activityItems: [img], applicationActivities: nil)
}
else {
shareButton.enabled = false
print("file missing!")
}
}
}
You can also add custom activities to the UIActivityViewController and here is code for adding an "Open In..." button to a UIActivityViewController so that you can switch to a UIDocumentInteractionController from a UIActivityViewController.
I did the same code for saving a PDF file from a URL (whether it's a local URL in your device storage, or it's a URL from somewhere on the internet)
Here is the Code for Swift 3 :
#IBOutlet weak var pdfWebView: UIWebView!
#IBOutlet weak var shareBtnItem: UIBarButtonItem!
var pdfURL : URL!
var docController : UIDocumentInteractionController!
then in viewDidLoad()
// retrieve URL to file in main bundle`
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("YOUR_FILE_NAME.pdf")
//Instantiate the interaction controller`
self.docController = UIDocumentInteractionController(url: fileURL)`
and in your barButtonItem tapped method (which I have called openIn(sender)):
#IBAction func openIn(_ sender: UIBarButtonItem)
{
// present UIDocumentInteractionController`
docController.presentOptionsMenu(from: sender, animated: true)
}
FYI: You need a webView in your storyboard if you wish to show the pdf file as well
Hope this helps.

Resources