Firebase, UIImageView and Kingfisher cache - issue with converting value - xcode

Im trying to implement Kingfisher image cache, with images hosted in firebase for my UITableView. However I'm having issues with converting the value types of imageView.kf.setImage..
The error I get is "Cannot convert value of type 'RetrieveImageTask' to type 'UIImageView' in coercion" this is related to the " let profileImage = imageView.kf.setImage(with: imageURL) as UIImageView" line of code below.
I don't seem to understand what imageView.kf.setImage is... I expected it to be an image within in an image view... but seems like it is something else..
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "feedCell") as? feedCell else
{print("dequeueResuableCell return an else"); return UITableViewCell() }
// data fro userdataArray
let imageURL = URL(string: userdataArray[indexPath.row].profileImage)
let imageView = UIImageView()
let profileImageView = imageView.kf.setImage(with: imageURL) as UIImageView
let profileName = userdataArray[indexPath.row].name
// data from activityArray
let activityDate = "8 October"
let distance = "8 km"
let activityName = "test"
let sightings = "20"
let kills = "10"
// Border styling
// cell.addBottomBorderWithColor(color: UIColor.lightGray, width: 0.5)
cell.clipsToBounds = true
// Shadow styling
cell.layer.shadowColor = UIColor.darkGray.cgColor
cell.layer.shadowOpacity = 0.25
cell.layer.shadowRadius = 1
cell.layer.shadowOffset = CGSize(width: 0, height: 1) // shadow on the bottom right
cell.layer.masksToBounds = false // important to show the shadow
cell.configureCell(profileImageView: profileImageView, profileName: profileName, activityDate: activityDate, ActivityName: activityName , distance: distance, sightings: sightings, kills: kills)
return cell
}
configureCell is in a separate view file
import UIKit
class feedCell: UITableViewCell {
#IBOutlet weak var profileImage: UIImageView!
#IBOutlet weak var profileName: UILabel!
#IBOutlet weak var activityDate: UILabel!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var distance: UILabel!
#IBOutlet weak var sightings: UILabel!
#IBOutlet weak var kills: UILabel!
func configureCell(profileImageView: UIImageView, profileName: String, activityDate: String, ActivityName: String, distance: String, sightings: String, kills: String) {
self.profileImage = profileImageView
self.profileName.text = profileName
self.activityDate.text = activityDate
self.name.text = ActivityName
self.distance.text = distance
self.sightings.text = sightings
self.kills.text = kills
}
}

You can't declare profileImageView with "imageView.kf.setImage(with: imageURL) as UIImageView" because It doesn't return anything.
You need to do like this;
let profileImageView = UIImageView()
profileImageView.kf.setImage(with: imageURL)

Related

NSPrintOperation View Is blank

Im still new to OSX / Swift 3.1 but Im a little stumped, Ive build an epos system and its work all fine, Im just stuck with printing out the receipt.
I have build a XIB View and the corresponding swift file for it show below
class Receipt: NSView {
let currentOrder = NewOrder.instance
#IBOutlet var view: NSView!
#IBOutlet weak var facebookString: NSTextField!
#IBOutlet weak var websiteString: NSTextField!
#IBOutlet weak var totalString: NSTextField!
#IBOutlet weak var vatString: NSTextField!
#IBOutlet weak var subTotalString: NSTextField!
#IBOutlet weak var CashierName: NSTextField!
#IBOutlet weak var orderNumber: NSTextField!
#IBOutlet weak var date: NSTextField!
#IBOutlet weak var itemList: NSTextField!
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
Bundle.main.loadNibNamed("ReceiptView", owner: self, topLevelObjects: nil)
let contentFrame = NSMakeRect(0, 0, frame.size.width, frame.size.height)
self.view.frame = contentFrame
self.addSubview(self.view)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
subTotalString.stringValue = "Hello World"
view.draw(dirtyRect)
subTotalString.draw(dirtyRect)
}
}
I have added the nib name to the XIB reference and loaded a new Receipt() class and added the view to the NSPrintOperation.
let order = NewOrder.instance
let sview = Receipt()
let printer = NSPrinter(name: "EPSON TM-T88V");
let printData = NSPrintInfo()
printData.printer = printer!
let printerName = printer?.name
let docSize = NSMakeSize(CGFloat(204.0), CGFloat(200));
let res = "180x180dpi";
let speed = "Auto";
let blank = "Off";
let paperCut = "DocFeedCut";
let chashDrwr1 = "After";
let chashDrwr2 = "Off";
let buzzerControl = "Off";
let buzzerPattern = "Internal";
let buzzerRepeat = "1";
let data = TMPrintSupport.tmSetJobTicket(printData, printerName: printerName, documentSize: docSize, resolution: res, speed: speed, blank: blank, paperCut: paperCut, chashDrwr1: chashDrwr1, chashDrwr2: chashDrwr2, buzzerControl: buzzerControl, buzzerPattern: buzzerPattern, buzzerRepeat: buzzerRepeat)
let po = NSPrintOperation(view: sview.view, printInfo: printData)
// po.showsPrintPanel = false
po.canSpawnSeparateThread = true
po.cleanUp()
return po.run()
When the print view is shown it is blank and does not contain the view and is blank, I've also test printed and the print is just blank.
Any suggestions welcome, thanks

Converting String from a label into Int

I have a button that adds 1 to an a attempt score label and then a button that adds a 1 or 0 to the correct score label depending which button is pressed. This data is then passed to various viewControllers. On the last viewController i want to convert the string from the label into a int and then do a simply calculation in order to get a percentage. The code i have tried is below. The percentage is not being displayed so I do not think i am converting it correctly?
On previous VC the aScore and cScore are set as variable that = 0. For example..
var aScore = 0
var cScore = 0
I am passing the data between VC and then on the final viewController the following code exits.
import UIKit
class gViewController: UIViewController {
#IBOutlet weak var correctScore: UILabel!
#IBOutlet weak var attemptScore: UILabel!
#IBOutlet weak var percentage: UILabel!
var aScore: Int!
var cScore: Int!
var percentage1: Int!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
correctScore.text = NSString(format: "%i", cScore) as String
attemptScore.text = NSString(format: "%i", aScore) as String
let c:Int? = Int(correctScore.text!)
let a:Int? = Int(attemptScore.text!)
percentage1 = c!/a!
percentage.text = NSString(format: "%i", percentage1) as String
}
Try this
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.correctScore.text = String(format: "%.1f", cScore)
self.attemptScore.text = String(format: "%.1f", aScore)
var percentage1 = Float(cScore)/Float(aScore)
self.percentage.text = String(format: "%.1f", percentage1)
}

Swift 2. Trying to unwrap a label.text! with NSNumberFormatter() included

Swift 2. I'm trying to use the answer of a label.text! to multiply again. The label is an optional but it has to be multiplied with a Double.
#IBOutlet weak var testLabel: UILabel!
#IBOutlet weak var first: UITextField!
#IBOutlet weak var second: UITextField!
func calculation1() {
let dfirst = Double(first.text!)
let dsecond = Double(second.text!)
if dfirst != nil && dsecond != nil {
let answerCal = ceil(dfirst! * dsecond!)
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .DecimalStyle
testLabel.text = numberFormatter.stringFromNumber(answerCal)
}
}
Any help will be appreciated.
First of all, apologies as I've put this together on a tablet meaning I cannot access the code editor. However, here's my take on your problem:
#IBOutlet weak var testLabel: UILabel!
#IBOutlet weak var first: UITextField!
#IBOutlet weak var second: UITextField!
func calculation1() -> Void {
// Check our two text fields contain text
guard let _ = first.text,
let _ = second.text else { return }
c // Check that the text can be parsed as Doubles
c guard let dfirst : Double = Double(first.text!),
let dsecond : Double = Double(second.text!) else { return }
// Now that we know we have two valid numbers, do the calculation
let answerCal : Double = ceil(dfirst! * dsecond!)
// Fetch a number formatter
let numberFormatter : NSNumberFormatter = {
let nF : NSNumberFormatter = NSNumberFormatter()
nF.numberStyle = .DecimalStyle
return nF
}()
// And update the text field with the answer if it produces a valid result
if let answerText : String = numberFormatter.stringFromNumber(answerCal) {
testLabel.text = answerText
}
}
You've got to be careful with UI elements where the user can theoretically type in anything and crash your app if you don't check it first. Hence the guard statements that will safely exit the method call if there is no text in the text fields or if those fields contain unusable text.
The reason you're getting an Optional back from your number formatter is because there is no guarantee that the formatter will be able to give you a valid string. Therefore you'll see that I've explicitly checked that the numbe formatter does generate a non-nil result before trying to update the text field.
(Note - I appreciate the closure for the number formatter is technically surplus to requirements but I find it clearer sometimes when configuring an object.)
UPDATE:
Vidal - did you try the code I sent you? I've quickly knocked up the following which is based on what I put together last night. It is obviously crude but shows that the methodology I suggested works fine, unless I'm missing something. The only issue I can think of is that you've done something in interface builder which I'm unaware of. Hope that helps!
import UIKit
class ViewController: UIViewController {
var calculatorView : UIView!
var textFieldOne : UITextField!
var textFieldTwo : UITextField!
var calButton : UIButton!
var answer : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.calculatorView = {
let cV : UIView = UIView(frame: CGRect(origin: CGPointZero, size: CGSizeMake(400, 400)))
cV.backgroundColor = UIColor.redColor()
func buildTextField() -> UITextField {
let tF : UITextField = UITextField()
tF.backgroundColor = UIColor.whiteColor()
tF.textColor = UIColor.blackColor()
tF.placeholder = "Please enter number"
return tF
}
self.textFieldOne = buildTextField()
self.textFieldTwo = buildTextField()
self.textFieldOne.frame = CGRect(origin: CGPointMake(20, 20), size: CGSizeMake(160, 50))
self.textFieldTwo.frame = CGRect(origin: CGPointMake(220, 20), size: CGSizeMake(160, 50))
self.calButton = {
let cB : UIButton = UIButton()
cB.setTitle("Calculate", forState: .Normal)
cB.frame = CGRect(origin: CGPointMake(20, 80), size: CGSizeMake(360, 50))
cB.addTarget(self, action: #selector(self.getAnswer), forControlEvents: UIControlEvents.TouchUpInside)
return cB
}()
self.answer = {
let a : UILabel = UILabel()
a.backgroundColor = UIColor.blueColor()
a.textColor = UIColor.whiteColor()
a.frame = CGRect(origin: CGPointMake(20, 140), size: CGSizeMake(360, 50))
return a
}()
cV.addSubview(textFieldOne)
cV.addSubview(textFieldTwo)
cV.addSubview(calButton)
cV.addSubview(answer)
return cV
}()
self.view.addSubview(calculatorView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getAnswer() -> Void {
// Check our two text fields contain text
guard let _ = self.textFieldOne.text,
let _ = self.textFieldTwo.text else { return }
// Check that the text can be parsed as Doubles
guard let dfirst : Double = Double(self.textFieldOne.text!),
let dsecond : Double = Double(self.textFieldTwo.text!) else { return }
// Now that we know we have two valid numbers, do the calculation
let answerCal : Double = ceil(dfirst * dsecond)
// Fetch a number formatter
let numberFormatter : NSNumberFormatter = {
let nF : NSNumberFormatter = NSNumberFormatter()
nF.numberStyle = .DecimalStyle
return nF
}()
// And update the text field with the answer if it produces a valid result
if let answerText : String = numberFormatter.stringFromNumber(answerCal) {
self.answer.text = answerText
}
}
}

CGColor not defined for the UIColor, need to first convert colorspace. Swift 2, Xcode 7

I was trying to change the color of my app´s buttons by creating the color using sliders to select the values of Red, Green, Blue and Alpha. So I created an variable which held the color created by the user.
ViewController is where the buttons are.
ChangeColors is the RGB Sliders System.
import UIKit
import Foundation
var buttonColor = UIColor()
class ViewController: UIViewController {
#IBOutlet var tools: UIButton!
#IBOutlet var custom: UIButton!
#IBOutlet var support: UIButton!
#IBOutlet var donate: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
tools.backgroundColor = buttonColor
custom.backgroundColor = buttonColor
support.backgroundColor = buttonColor
donate.backgroundColor = buttonColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The second is the code of te RGB Slider System.
import Foundation
import UIKit
class ChangeColors: UIViewController {
#IBOutlet var Red: UISlider!
#IBOutlet var Green: UISlider!
#IBOutlet var Blue: UISlider!
#IBOutlet var Alpha: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func preview(sender: AnyObject) {
let rVal = CGFloat(Red.value)
let gVal = CGFloat(Green.value)
let bVal = CGFloat(Blue.value)
let aVal = CGFloat(Alpha.value)
self.view.backgroundColor = UIColor(red: rVal, green: gVal, blue: bVal, alpha: aVal)
}
#IBAction func change(sender: AnyObject) {
let rVal = CGFloat(Red.value)
let gVal = CGFloat(Green.value)
let bVal = CGFloat(Blue.value)
let aVal = CGFloat(Alpha.value)
let color = UIColor(red: rVal, green: gVal, blue: bVal, alpha: aVal)
buttonColor = color
}
}
But the app crashes as soon as it open and get the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -CGColor not defined for the UIColor ; need to first convert colorspace.
I really need help. Thank You.
The problem is that an instance created by the UIColor() initialiser doesn't represent an actual color. If you look at the crash message in more detail, you'll see that it actually creates a UIPlaceholderColor instance – which (as the name suggests) appears to act as a 'placeholder' in the absence of any color information. Therefore you can't assign it to the backgroundColor of any of your views.
The fix is define a default color for your buttonColor. In your case I'd advise clearColor.
var buttonColor = UIColor.clearColor()

Optional() in my text view

For one of my static labels on my main story board, it prints out "Optional("United States"). However, I would like it to print out "United States". So my question is, how do I get rid of the "Optional" part? I've already tried doing:
if let p = placemarks!.first{
self.addressLabel.text = "\(p.country)"
}
I think the exclamation mark is supposed to "unwrap" some value right? However, even if I do p = placemarks!.first, it prints out "Optional("United States").
Below is the rest of my code just in case you would like some context:
//
// ViewController.swift
// Map Demo Rob 2
//
// Created by Jae Hyun Kim on 8/17/15.
// Copyright © 2015 Jae Hyun Kim. All rights reserved.
//
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var latitudeLabel: UILabel!
#IBOutlet weak var longitudeLabel: UILabel!
#IBOutlet weak var courseLabel: UILabel!
#IBOutlet weak var speedLabel: UILabel!
#IBOutlet weak var altitudeLabel: UILabel!
#IBOutlet weak var addressLabel: UILabel!
var manager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
let userLocation: CLLocation = locations[0]
self.latitudeLabel.text = "\(userLocation.coordinate.latitude)"
self.longitudeLabel.text = "\(userLocation.coordinate.longitude)"
self.courseLabel.text = "\(userLocation.course)"
self.speedLabel.text = "\(userLocation.speed)"
self.altitudeLabel.text = "\(userLocation.altitude)"
CLGeocoder().reverseGeocodeLocation(userLocation, completionHandler: {(placemarks, error) -> Void in
print(userLocation)
if error != nil {
print(error)
return
}
else {
if let p = placemarks?.first{
self.addressLabel.text = "\(p.country)"
}
}
})
}
}
In
if let p = placemarks!.first{
self.addressLabel.text = "\(p.country)"
}
p.country is an Optional<String>. You need to unwrap that aswell in order to output only it's content (if it exists).
if let country = placemarks?.first?.country {
self.addressLabel.text = country
}

Resources