swiftEntryKit custom pop up nib not loading data - ios

I have a custom popup from a nib using swiftEntryKit which displays data from the user the currentUser has clicked on.
I have a nib file called UserRequestView
and a UIView class called UserRequestView
I also have another UIView class called UserRequestPreviewView which is the nibs custom class and sets up all of the data on the nib file
when the currentUser selects another user from a collectionView inside of NewHomeViewController the currentUser is presented with a popup screen asking whether to send a friend request. To present the popup view I use this:
`SwiftEntryKit.display(entry: UserRequestView(), using: popupAttributes)`
and to load data into the nib:
if let popupView = Bundle.main.loadNibNamed("UserRequestView", owner: self, options: nil)!.first as? UserRequestPreviewView {
popupView.currentUser = self.currentUser
popupView.user = self.users[self.theUserIndex]
}
When running the project and clicking on to a user, the popup is displayed fine and the data has loaded into the nib, However, the images and text on the nib have not changed.
for more context, here is the UserRequestView class:
class UserRequestView: UIView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
init() {
super.init(frame: .zero)
setup()
}
private func setup() {
fromNib()
}
}
the method fromNib is an extension of UIView:
extension UIView {
#discardableResult
func fromNib<T : UIView>() -> T? {
guard let contentView = Bundle(for: type(of: self)).loadNibNamed(type(of: self).className, owner: self, options: nil)?.first as? T else {
return nil
}
addSubview(contentView)
contentView.fillSuperview()
return contentView
}
}
and the class I use to setup the nib to display the data:
class UserRequestPreviewView: UIView {
#IBOutlet weak var userProfileImage: roundedImage!
#IBOutlet weak var userFirstLastName: UILabel!
#IBOutlet weak var usersBirthday: UILabel!
#IBOutlet weak var friendsOptionBtn: UIButton!
var currentUser: User!
var user: User! {
didSet {
if currentUser != nil {
print("the current user = \(currentUser.firstName)")
print("this user = \(user.firstName)")
setUp()
}
}
}
var cache = SAMCache.shared()
override func awakeFromNib() {
super.awakeFromNib()
layer.applySketchShadow()
layer.cornerRadius = 20
layer.masksToBounds = false
friendsOptionBtn.layer.cornerRadius = friendsOptionBtn.bounds.height / 2.0
friendsOptionBtn.layer.masksToBounds = true
userProfileImage.layer.cornerRadius = userProfileImage.bounds.height / 2.0
userProfileImage.layer.masksToBounds = true
friendsOptionBtn.isEnabled = true
}
func setUp(){
print("got to set up")
let profileImageKey = "\(user.uid)-profileImage"
if let image = cache?.object(forKey: profileImageKey) as? UIImage{
self.userProfileImage.image = image
print("setting image 1")
}else{
user.downloadProfilePicture { [weak self] (image, error) in
if let image = image {
self?.userProfileImage.image = image
print("setting image 2")
self?.cache?.setObject(image, forKey: profileImageKey)
}else if error != nil {
print(error)
}
}
}
userFirstLastName.text = "\(user.firstName) \(user.lastName)"
usersBirthday.text = "\(user.birthday)"
}
}
I know that the currentUser and user have been set into the nib because the print statements show in the console
"got to set up" prints and so does "setting image 1"
I don't understand why the images and text are not displaying in the nib. Does anyone have a solution? thanks.

Related

Programmatically set the row height for a tableview controller with varying image aspect ratios?

Currently I'm working on a media feed that may contain images in varying aspect ratios. Each image is to be scaled to the same width on the screen and the height will be adjusted according to the same ratio.
My tableViewController is using automatic dimensions. Each image is scaled to the correct width and height then a new image is created which is fed into its corresponding tableViewCell.
However, when the width and height is set programmatically (via auto dimension and the scaled image), I find a strange bug where I have to scroll around to get the image to display. (Video below). It's not until I use heightForRowAt and use a constant value where the aspect ratio is not preserved that the images display at the apps launch.
I'd love to be able to display these images in their correct aspect ratio. Any help is definitely appreciated.
Thanks!
First Image: auto dimension
Images display after scrolling action (maybe a bug)
Second Image: height for row at
TableVC cell class
import UIKit
import Firebase
class UserPostCell: UITableViewCell {
// MARK: - Outlets
#IBOutlet private weak var userProfileBtn: UIButton!
#IBOutlet private weak var likeBtn: UIButton!
#IBOutlet private weak var captionTxtField: UITextField!
#IBOutlet weak var postImage: UIImageView!
private(set) var height: CGFloat?
override func awakeFromNib() {
super.awakeFromNib()
}
func configureCell(post: UserPost) {
let gsReference = Storage.storage().reference(forURL: post.photoURL)
var image: UIImage?
gsReference.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
debugPrint("Error: \(error.localizedDescription)")
} else {
image = UIImage(data: data!)
//let h = image!.size.height
let w = image!.size.width
let wRatio = self.frame.size.width / w
//create new image at correct scale
let newImage = UIImage(data: data!, scale: 1 / wRatio)
self.postImage.frame.size.height = newImage!.size.height
self.postImage.image = newImage
self.userProfileBtn.setTitle(post.username, for: .normal)
self.captionTxtField.text = post.caption
}
}
}
}
View Controller
import UIKit
import Firebase
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
// MARK: - Outlets
#IBOutlet private weak var tableView: UITableView!
// MARK: - Variables
private var userPosts = [UserPost]()
private var postsCollectionRef: CollectionReference!
private var usersCollectionRef: CollectionReference!
private var handle: AuthStateDidChangeListenerHandle?
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 450
postsCollectionRef = Firestore.firestore().collection(POSTS_REF)
usersCollectionRef = Firestore.firestore().collection(USERS_REF)
loadPosts()
}
func loadPosts() {
var username: String?
var profileURL: String?
//var photoURL: String?
var uid: String?
//retrieve posts from database
postsCollectionRef.getDocuments { snapshot, error in
if let err = error {
debugPrint(err.localizedDescription)
} else {
guard let snap = snapshot else { return }
for d in snap.documents {
let data = d.data()
uid = data[USER_ID] as? String ?? ""
//retrieve info about author of each post
let userDocRef = self.usersCollectionRef.document(uid!)
//retrieve user info for each post
userDocRef.getDocument { document, error in
if let document = document, document.exists {
let dat = document.data()
//user data (dat)
username = dat![USERNAME] as? String ?? "Anonymous"
profileURL = dat![PROFILE_IMAGE] as? String ?? ""
// dat vs data fix this ^^^
//post data (data)
let photoURL = data[PHOTO_URL] as? String ?? ""
let caption = data[CAPTION] as? String ?? ""
let numComments = data[NUM_COMMENTS] as? Int ?? 0
let numLikes = data[NUM_LIKES] as? Int ?? 0
let timestamp = data[TIME_STAMP] as? Date ?? Date()
let documentId = d.documentID
print("photolink: \(photoURL)")
print("caption: \(caption)")
let newPost = UserPost(name: username!, timestamp: timestamp, caption: caption, numLikes: numLikes, numComments: numComments, documentId: documentId, UID: uid!, profile: profileURL!, photo: photoURL)
self.userPosts.append(newPost)
self.tableView.reloadData()
} else {
print("This user document does not exist")
}
}
}
}
}
}
override func viewWillAppear(_ animated: Bool) {
//check if the user is logged in or not
handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
if user == nil {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVC = storyboard.instantiateViewController(identifier: "loginVC")
self.present(loginVC, animated: true, completion: nil)
} else {
//self.loadPosts()
// set listener
self.tableView.reloadData()
}
})
}
#IBAction func logoutBtnTapped(_ sender: Any) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
} catch let signoutError as NSError {
debugPrint("Error signing out: \(signoutError)")
}
}
#IBAction func reload(_ sender: Any) {
self.tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userPosts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "userPostCell", for: indexPath) as? UserPostCell{
cell.configureCell(post: userPosts[indexPath.row])
return cell
} else {
return UITableViewCell()
}
}
}
The reason of this your cell is already created before UIImage loads up.
Best way to prevent this, give one of the constraints of the imageView.

Why is a lazy var accessing a class property before this one had a value?

I have a ViewController that has a lazy UIView property:
class DetailView: UIViewController {
var presenter: DetailPresenterProtocol?
var heroData: MarvelData?
var marvelDataCollection: [MarvelData]? {
didSet {
print("Initialized")
}
}
lazy var bodyView: BodyDetailView = {
print("Inside lazy var initialization")
guard let data = marvelDataCollection else { return BodyDetailView(data: [], elems: "")}
print(data)
let body = BodyDetailView(data: data, elems: heroData?.description ?? "No description")
return body
}()
///More stuff over here
}
// MARK: - Lifecycle
extension DetailView {
override func viewDidLoad() {
super.viewDidLoad()
presenter?.viewDidLoad()
title = heroData?.name ?? "No name"
setupViews()//Here I set the lazy UIView
print("Finished view did load")
}
}
The problem is when unwrape data inside the lazy var, it is nil because "marvelDataCollection" has no value already.
This is the flow:
Inside lazy var initialization
Finished view did load
Initialized
What am I doing wrong?
Thanks
I found a possible solution that is based on calling the setupViews() inside the presenter callback(just after class properties instantiation) instead of viewDidLoad:
//MARK: - Presenter -> View
extension DetailView: DetailViewProtocol {
func saveData(data: [MarvelData]) {
marvelDataCollection = data
setupViews()
}
func setupView(with data: MarvelData) {
heroData = data
}
}

what is better approach to UITextField validations on iOS?

I have to make validation on ui text field which used in library called RSFloatInputView.
Here is my xib
import UIKit
import RSFloatInputView
class TextInputLayout: UIView {
#IBOutlet weak var revealButton: UIButton!
#IBOutlet weak var warningLabel: UILabel!
#IBOutlet weak var rsFloatingView: RSFloatInputView!
var contentView: UIView?
override init(frame: CGRect) {
super.init(frame: frame)
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
func xibSetup() {
contentView = loadViewFromNib()
contentView!.frame = bounds
contentView!.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth, UIView.AutoresizingMask.flexibleHeight]
addSubview(contentView!)
}
func loadViewFromNib() -> UIView! {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: "TextInputLayout", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
revealButton.tintColor = Color.grayColor()
warningLabel.textColor = UIColor.red
return view
}
}
I want to implement this in this view controller, when i click on next button
import UIKit
import DLRadioButton
class SecureWalletViewController: UIViewController,UITextFieldDelegate {
#IBOutlet weak var securityPinStackView: UIStackView!
#IBOutlet weak var securityPin: TextInputLayout!
#IBOutlet weak var confirmSecurityPin: TextInputLayout!
#IBAction func onNextButtonTap(_ sender: Any) {
}
func textInputLayout(at index:Int) -> TextInputLayout {
return securityPinStackView.arrangedSubviews[index] as! TextInputLayout
}
}
Use validations for UITextFieldDelegate method like given below:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return true
}
Or use custom validation function Here
Iam using this
// add func in swift class
struct validatorConstants{
static let errorMsg = "your error messages"
static let customMsg = "your error messages"
static let emailMsg = "your error messages"
}
class Validators: NSObject {
//MARK: Validation on any Empty TextField
func validators(TF1:UITextField,errorMsg:String = validatorConstants.errorMsg,fieldName:String = "") -> Bool {
var error = validatorConstants.errorMsg
if fieldName.count > 0 {
error = fieldName + " is missing"
}
if TF1.text?.isEmpty == true{
kAppDelegate.showNotification(text: error)
return false
}
return true
}
//MARK: Validation on any Email TextField
func validatorEmail(TF1:UITextField,errorMsg:String = validatorConstants.errorMsg ,errorMsgEmail:String = validatorConstants.emailMsg,fieldName:String = "Email" ) -> Bool {
var error = validatorConstants.errorMsg
if fieldName.count > 0 {
error = fieldName + " is missing"
}
if TF1.text?.isEmpty == true{
kAppDelegate.showNotification(text: error)
return false
}
if TF1.text?.isValidEmail == false{
kAppDelegate.showNotification(text: errorMsgEmail)
return false
}
return true
}
}
// call this func like this
// your ViewController
var validator:Validators!
// In viewdidload
validator = Validators()
// call this func on button Action
guard validator.validators(TF1: txtfied,fieldName: "your txtfield name") == false
else
{
//do something what you want
return
}
// Its works for me hope its works for you
I'd recommend to use a UITextField subclass with 2 UI states (regular / invalid) and a validation rule (e.g. not empty / match regex / etc)
class ValidationTextField: UITextField {
enum ValidationRule {
case notEmpty
// case matchRegex(regex: NSRegularExpression)
// ...
}
var validationRule: ValidationRule?
private(set) var isValid:Bool = true {
didSet {
updateUIForCurrentState()
}
}
// Call this method on the "next" button click
// (or from the delegate on the textFieldDidEndEditing event for early validation)
func validate() {
guard let rule = validationRule else {
// nothing to validate
return;
}
switch rule {
case .notEmpty:
if let length = text?.count {
isValid = length > 0
}
else {
isValid = false
}
// process other cases (e.g. matchRegex)
}
}
/// Configure your state-specific layout here.
private func updateUIForCurrentState() {
// Current implementation adds a red border in case of invalid input
if isValid {
layer.borderWidth = 0
layer.borderColor = nil
}
else {
layer.borderWidth = 2
layer.borderColor = UIColor.red.cgColor
}
}
}
You can use SwiftValidator, It is rule based validator.
let validator = Validator()
//Register the fields that you want to validate
validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()])
#IBAction func signupTapped(sender: AnyObject) {
validator.validate(self)
}

swift protocol delegate always return nil

I have this protocol delegate defined in my View Controller:
protocol PickerDelegate : NSObjectProtocol {
func updateMessage(meesage: String)
}
and then I called this in my View Controller:
class GradingController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, SDataGridDataSourceHelperDelegate, SLAIssuedFinalGradingDelegate, CityApprovalIssuedDelegate, CityCommentReceivedDelegate, DepositReceivedDelegate, UIPopoverPresentationControllerDelegate {
var pickerDelegate: PickerDelegate?
}
And then I am calling my method inside the protocol delegate (this is where its nil):
func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
let controller = popoverPresentationController.presentedViewController as! CommentsController
pickerDelegate?.updateMessage(meesage: controller.commentView.text)
}
And I am using this delegate in my custom class:
class TextCell: SDataGridCell, PickerDelegate {
var dataGrid: ShinobiDataGrid?
private var _commentText = ""
private var label: UILabel?
var commentText: String {
get {
return _commentText
}
set(commentText) {
if(commentText != "")
{
label?.text = commentText
}
else
{
label?.text = "N/A"
}
}
}
override init(reuseIdentifier identifier: String!) {
super.init(reuseIdentifier: identifier)
label = UILabel()
label?.font = UIFont.systemFont(ofSize: 15)
label?.frame = CGRect(x: 0, y: 0, width: 200, height: 32)
addSubview(label!)
let pickerViewController = GradingController()
pickerViewController.pickerDelegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func respondToEditEvent() {
if dataGrid?.delegate.responds(to: #selector(SDataGridDelegate.shinobiDataGrid(_:shouldBeginEditingCellAtCoordinate:))) ?? false {
if dataGrid?.delegate.shinobiDataGrid!(dataGrid, shouldBeginEditingCellAtCoordinate: coordinate) == false {
return
}
}
if dataGrid?.delegate.responds(to: #selector(SDataGridDelegate.shinobiDataGrid(_:willBeginEditingCellAtCoordinate:))) ?? false {
dataGrid?.delegate.shinobiDataGrid!(dataGrid, willBeginEditingCellAtCoordinate: coordinate)
}
}
func updateMessage(meesage: String) {
commentText = meesage
}
}
But the updateMessage method is not being called, my delegate is nil in my View Controller when I try to use it in popoverPresentationControllerDidDismissPopover but it always return nil :(
What am I doing wrong?
This is the TextCell in GradingController:
func dataGridDataSourceHelper(_ helper: SDataGridDataSourceHelper!, populateCell cell: SDataGridCell!, withValue value: Any!, forProperty propertyKey: String!, sourceObject object: Any!) -> Bool {
let cellDataObj = object as? GradingData
if(propertyKey == "GradingRepair")
{
let textCell = cell as? TextCell
textCell?.dataGrid = self.grid
textCell?.commentText = (cellDataObj?.GradingRepair)!
return true
}
return false
}
Consider what this code does:
let pickerViewController = GradingController() // 1
pickerViewController.pickerDelegate = self // 2
// 3
You create a completely new GradingController.
You assign the GradingController a pickerDelegate.
Nothing. So you throw the GradingController away. Your code thus has no effect on anything.
What you need to do is to assign a pickerDelegate to the actual GradingController that's in your interface. But that's not what you did.

Parse Data on Koloda Library - can not display on view

Can someone please tell me what am I doing wrong?
Probably a lot cos I am newbie, but looking forward to solve this!
I am using Koloda libray (https://github.com/Yalantis/Koloda/tree/networking_example) to fetch an Array of Objects into the Card so every card gets a row from my database. I have seen the networking exemple with Alamofire and tried my own code that implements Parse using the same exemple. It is getting the objects from Parse but I have not been able to display them into the cards. Weird, actually I have no errors and the console display "Successfully retrieved 5 objects", but this is only the loadData() function.
I am going to display a lot of text there from a nib!
What am I basically trying to achieve:
I have (MyView.xib, MyView.swift) that provides the labels.
(What I want, is to retrieve from the array to texts into the labels from xib)
I am retrieving the objects but I have not been successful on displaying them into the card:
Successfully retrieved 5 posts.
Optional("EvUICgRQ6E")
Optional("5kC0FLKQON")
Optional("1Uyxb2M1Et")
Optional("aeJpRCG7Qn")
Optional("GDmGh3IULm")
Some Errors:
If I am returning the "numberOfCards" --- I am getting this error:
fatal error: Array index out of range
(lldb)
If I return: "return UInt (self.data.count)"
I am not getting any errors but the cards are not being displayed at all.
I am a bit of a newbie, but pointed into a good direction I will be able to get it done.
This is my ViewController.swift code:
//
// ViewController.swift
// TinderCardsSwift
//
// Created by Eugene Andreyev on 4/23/15.
// Copyright (c) 2015 Eugene Andreyev. All rights reserved.
//
import UIKit
import Koloda
import pop
import Parse
import ParseUI
private var numberOfCards: UInt = 5
class ViewController: UIViewController, KolodaViewDataSource, KolodaViewDelegate {
#IBOutlet weak var kolodaView: KolodaView!
#IBOutlet weak var menuLeft: UIBarButtonItem!
#IBOutlet weak var searchRight: UIBarButtonItem!
var cardsCollection: [MyView] = []
var labelText3 = ""
var labelText4 = ""
var currentObject:PFObject?
override func viewDidLoad() {
super.viewDidLoad()
kolodaView.dataSource = self
kolodaView.delegate = self
menuLeft.target = self.revealViewController()
menuLeft.action = Selector("revealToggle:")
searchRight.target = self.revealViewController()
searchRight.action = Selector("rightRevealToggle:")
self.modalTransitionStyle = UIModalTransitionStyle.FlipHorizontal
loadData()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
//MARK: Geting Data From Parse and displaying 5 posts with a print result - WORKING
func loadData (){
if (!cardsCollection.isEmpty) {
self.kolodaView.reloadData()
return
}
let query = PFQuery(className:"Countries")
query.orderByAscending("nameEnglish")
query.findObjectsInBackgroundWithBlock {
(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) posts.")
// Do something with the found objects
if let objects = objects {
for object in objects {
let view = NSBundle.mainBundle().loadNibNamed("MyView", owner: self, options: nil)[0] as! MyView
view.label1.text = object["nameEnglish"] as? String
view.label2.text = object["capital"] as? String
self.cardsCollection += [view]
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
self.kolodaView.reloadData()
return
}
/*func printData () {
let dataView = NSBundle.mainBundle().loadNibNamed("MyView",
owner: self, options: nil)[0] as? MyView
if let nameEnglish = object?["nameEnglish"] as? String {
let lbl2 = dataView?.label1 as UILabel!
lbl2!.text = nameEnglish
}
//return printData()
}*/
#IBAction func logOut4(sender: AnyObject) {
// Send a request to log out a user
PFUser.logOut()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let viewController:UIViewController = UIStoryboard(name: "SlideMain", bundle: nil).instantiateViewControllerWithIdentifier("Login_Platform")
self.presentViewController(viewController, animated: true, completion: nil)
})
}
override func viewWillAppear(animated: Bool) {
if (PFUser.currentUser() == nil) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let viewController:UIViewController = UIStoryboard(name: "SlideMain", bundle: nil).instantiateViewControllerWithIdentifier("Login_Platform")
self.presentViewController(viewController, animated: true, completion: nil)
})
}
}
//MARK: IBActions
#IBAction func leftButtonTapped() {
kolodaView?.swipe(SwipeResultDirection.Left)
}
#IBAction func rightButtonTapped() {
kolodaView?.swipe(SwipeResultDirection.Right)
}
#IBAction func undoButtonTapped() {
kolodaView?.revertAction()
}
//MARK: KolodaViewDataSource
func kolodaNumberOfCards(koloda: KolodaView) -> UInt {
return numberOfCards
//return UInt (self.data.count)
//return UInt(cardsCollection.count)
}
func kolodaViewForCardAtIndex(koloda: KolodaView, index: UInt) -> UIView {
//return UIImageView(image: UIImage(named: "Card_like_\(index + 1)"))
return (NSBundle.mainBundle().loadNibNamed("MyView",
owner: self, options: nil)[0] as? MyView)!
//let view = cardsCollection[Int(index)]
//return view
/* let dataView = NSBundle.mainBundle().loadNibNamed("MyView",
owner: self, options: nil)[0] as? MyView
let parseData = data[Int(index)]
dataView?.label1?.text = parseData.labelText
dataView?.label2?.text = parseData.label2Text
return dataView!*/
}
func kolodaViewForCardOverlayAtIndex(koloda: KolodaView, index: UInt) -> OverlayView? {
return NSBundle.mainBundle().loadNibNamed("OverlayView",
owner: self, options: nil)[0] as? OverlayView
}
//MARK: KolodaViewDelegate
func kolodaDidSwipedCardAtIndex(koloda: KolodaView, index: UInt, direction: SwipeResultDirection) {
//Example: loading more cards
if index >= 3 {
numberOfCards = 5
kolodaView.reloadData()
}
}
func kolodaDidRunOutOfCards(koloda: KolodaView) {
//Example: reloading
kolodaView.resetCurrentCardNumber()
loadData()
}
func kolodaDidSelectCardAtIndex(koloda: KolodaView, index: UInt) {
UIApplication.sharedApplication().openURL(NSURL(string: "http://yalantis.com/")!)
}
func kolodaShouldApplyAppearAnimation(koloda: KolodaView) -> Bool {
return true
}
func kolodaShouldMoveBackgroundCard(koloda: KolodaView) -> Bool {
return true
}
func kolodaShouldTransparentizeNextCard(koloda: KolodaView) -> Bool {
return true
}
func kolodaBackgroundCardAnimation(koloda: KolodaView) -> POPPropertyAnimation? {
return nil
}
}
This is MyView.swift (where I defined everything)
//
// MyView.swift
//
//
// Created by Viorel Petrisor on 12/29/15.
// Copyright © 2015 Viorel Petrisor. All rights reserved.
//
import UIKit
class MyView: UIView {
#IBOutlet var label1: UILabel!
#IBOutlet var label2: UILabel!
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
}
MyView has it's own nib.
Gonna place some pictures with my project also:
KolodaView in my Main StoryBoard
Does anybody knows how to make this work? I have been struggling for 10 days now and still didn't get it to work.
I would deeply appreciate some help, hints!
UPDATE: I am now using this function for loadData()
func loadData (){
if (!cardsCollection.isEmpty) {
self.kolodaView.reloadData()
return
}
let query = PFQuery(className:"Countries")
query.orderByAscending("nameEnglish")
query.findObjectsInBackgroundWithBlock {
(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
// The find succeeded.
print("Successfully retrieved \(objects!.count) posts.")
// Do something with the found objects
if let objects = objects {
for object in objects {
let view = NSBundle.mainBundle().loadNibNamed("MyView", owner: self, options: nil)[0] as! MyView
view.label1.text = object["nameEnglish"] as? String
view.label2.text = object["capital"] as? String
self.cardsCollection += [view]
print(object.objectId)
}
}
} else {
// Log details of the failure
print("Error: \(error!) \(error!.userInfo)")
}
}
self.kolodaView.reloadData()
return
}
WITH this variable
var cardsCollection: [MyView] = []
I had a similar issue with the Card not getting the data. Apparently, it was a problem with how I was calling the Bundle. Correct Swift 3.0 code below.
func koloda(_ koloda: KolodaView, viewForCardAt index: Int) -> UIView {
let bundle = Bundle(for: MyView.self) // This gets the correct bundle for your class, as sometimes you might have many bundles.
let nib = UINib(nibName: String(describing: MyView.self), bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! MyView
return view
}
Could you please add an issue on GitHub? https://github.com/Yalantis/Koloda/issues
thank you

Resources