I am creating an App on Xcode7 using swift and I really need some help. I would like to make the SWRevealViewController sidebar appear on all of my scene but the problem is it only appears on the first view controller I set the push segue to show. And also upon clicking a link on the sidebar the navigation bar disappears on the next scene? Please somebody help...
sidebar
Here is the script I used on my UITableViewController for the sidebar links
var catArrayId = [String]()
var catArrayName = [String]()
var catArrayImg2 = [String]()
override func viewDidLoad(){
// get available categories according to customer country
get_categories()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return catArrayId.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("navCell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = self.catArrayName[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("showCategory", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showCategory" {
let VC = segue.destinationViewController as! CategoryProductsViewController
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
let categoryImage = UIImage(named: catArrayImg2[indexPath.row])
VC.catId = self.catArrayId[indexPath.row]
VC.image = categoryImage!
}
}
func get_categories(){
let country_id = 168
//let startTime = NSDate.timeIntervalSinceReferenceDate()
let pageUrl = "https://domain.com/ios/home-categories-image.php?country_id=\(country_id)&uudi=" + NSUUID().UUIDString
let myUrl = NSURL(string: pageUrl)
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "GET"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request){
(let data, let response, let error) in
if(error != nil){
print(error?.localizedDescription)
return
}
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
let catArray = json as? [[String: AnyObject]]
for catArr in catArray!{
let catName = catArr["name"] as? String
let catID = catArr["id"] as? String
let img2 = catArr["image2"] as? String
dispatch_async(dispatch_get_main_queue(), {
self.catArrayId.append(catID!)
self.catArrayName.append(catName!)
self.catArrayImg2.append(img2!)
self.tableView.reloadData()
})
}
}
catch{
print("Error serializing JSON: \(error)")
}
}
task.resume()
}
If I understood your question right, then you can do the same as in example provided by an author of controller ("RevealControllerStoryboardExample2"). When you select something from rear VC, segue for that action needs to have class "SWRevealViewControllerSeguePushController". Here is a screenshot of this example:
Related
I have a tableview.
Each cell opens a new ViewController and loads a .txt file to a textview from my github repo.
But now i want to make each cells to load a different .txt file from the same repo.
So like the first cell loads the first.txt, the second loads the second.txt and so on
is this even possible?
It would be like a news reader app where you click on a title and can read the article.
Here is my current code which is bad but im a beginner :(
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let content = self.downloadContent()
DispatchQueue.main.async {
self.myTextView.text = content
}
}
}
func downloadContent() -> String {
var data : Data!
data = try? Data(contentsOf: URL(string: "https://raw.githubusercontent.com/SiposPtr/umszkiapp/master/cikk2.txt")!)
let data_str = String(data: data, encoding: .utf8)
return data_str!
}
I upload my files to a new github repo so you can see the whole stuff:
https://github.com/SiposPtr/stackoverflow
Could you please check if this is working?
import UIKit
class TableViewController: UITableViewController {
var TableData: Array<String> = Array<String>()
var currentCell: String?
var selectedValue: String?
var numberOfFileToLoad: Int = 1
override func viewDidLoad() {
super.viewDidLoad()
get_data_from_url("https://raw.githubusercontent.com/SiposPtr/umszkiapp/master/cimek.json")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = TableData[indexPath.row]
cell.textLabel!.numberOfLines = 2;
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 90.0;
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedValue = TableData[indexPath.row]
numberOfFileToLoad = indexPath.row + 1
}
func get_data_from_url(_ link:String)
{
let url:URL = URL(string: link)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
self.extract_json(data!)
})
task.resume()
}
func extract_json(_ data: Data) {
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
}
catch
{
return
}
guard let data_list = json as? NSArray else
{
return
}
if let hir_lista = json as? NSArray {
for i in 0 ..< data_list.count
{
if let hir_obj = hir_lista[i] as? NSDictionary
{
if let cim_nev = hir_obj["cim"] as? String
{
if let hir_code = hir_obj["datum"] as? String
{
TableData.append(cim_nev + "\n(" + hir_code + ")")
}
}
}
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
// ez működik, de a run utáni első cikknek üres a titléje és akk csúszik minden cím eggyel
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "gotoSentences"{
let nextViewController = segue.destination as! HirNezetViewController
nextViewController.title = selectedValue
print(selectedValue)
nextViewController.numberOfFileToLoad = numberOfFileToLoad
print(numberOfFileToLoad)
}
}
#IBAction func reloadButton(_ sender: Any) {
let alert = UIAlertController(title: "A cikkeket újratöltöttem", message: "Kattints a gombra az eltüntetéshez", preferredStyle: .alert)
let ok = UIAlertAction(title: "Rendben", style: .default, handler: { action in
})
alert.addAction(ok)
get_data_from_url("https://raw.githubusercontent.com/SiposPtr/umszkiapp/master/cimek.json")
tableView.reloadData()
}
}
import UIKit
class HirNezetViewController: UIViewController {
var data:String!
var content: String?
var numberOfFileToLoad: Int = 1
#IBOutlet weak var myTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let content = self.downloadContent()
DispatchQueue.main.async {
self.myTextView.text = content
}
}
}
func downloadContent() -> String {
var data : Data!
data = try? Data(contentsOf: URL(string: "https://raw.githubusercontent.com/SiposPtr/umszkiapp/master/cikk\(String(numberOfFileToLoad)).txt")!)
let data_str = String(data: data, encoding: .utf8)
return data_str!
}
}
Here is my code, it is supposed to display the users inside firebase database in customs tableviewcell.xib but when launching the app the tableview stays empty, I really don't know what's wrong in the code or what's missing, I think it is a really simple mistake but I can't figure it out.
Thanks in advance for those who will answer.
import UIKit
import Firebase
class UsersTableView: UIViewController, UITableViewDelegate, UITableViewDataSource {
// Outlets.
#IBOutlet weak var tableview: UITableView!
// Var.
var user = [User]()
override func viewDidLoad() {
super.viewDidLoad()
retrieveUsers()
// Do any additional setup after loading the view.
}
func retrieveUsers() {
let ref = Database.database().reference()
ref.child("users").queryOrderedByKey().observeSingleEvent(of: .value, with: { DataSnapshot in
let users = DataSnapshot.value as! [String: AnyObject]
self.user.removeAll()
for (_, value) in users{
//let uid = Auth.auth().currentUser!.uid
if let uid = value["userID"] as? String{
if uid != Auth.auth().currentUser!.uid {
let userToShow = User()
if let fullName = value["username"] as? String , let imagePath = value["photoURL"] as? String {
userToShow.username = fullName
userToShow.imagePath = imagePath
userToShow.userID = uid
self.user.append(userToShow)
}
}
}
}
self.tableview.reloadData()
})
ref.removeAllObservers()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableview.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath) as! UserTableViewCell
cell.nameLabel.text = self.user[indexPath.row].username
cell.userID = self.user[indexPath.row].userID
cell.userImage.downloadImage(from: self.user[indexPath.row].imagePath!)
//checkFollowing(indexPath: indexPath)
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return user.count ?? 0
}
}
extension UIImageView{
func downloadImage(from imgURL: String!) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil{
print(error)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
If you have not set delegate and datasource for your tableView in your storyboard do it programmatically:
override func viewDidLoad() {
super.viewDidLoad()
//Add these 2 lines, might be missed.
self.tableview.delegate = self
self.tableview.dataSource = self
retrieveUsers()
}
CheckList:
Set tableView Delegate and Datasource
self.tableview.delegate = self
self.tableview.dataSource = self
Registered custom tableViewCell?
let cellNIb = UINib.init(nibName:"Identifier_Name", bundle: nil)
register(cellNIb, forCellReuseIdentifier: identifier)
check the return count of func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
There are two things that you forgot:
Set dataSource of your table view as your controller. If you don't do it, your tableView won't want any data. So set it in controller's viewDidLoad
tableview.dataSource = self
If you created custom xib for your cell, don't forget to register your custom cell for table view (also you can do it in viewDidLoad)
tableview.register(UINib(nibName: "UserCardTableViewCell", bundle: nil), forCellReuseIdentifier: "UserCell")
If you need UITableViewDelegate methods like didSelectRowAt too, don't forget to set delegate of your table view as your controller too
tableview.delegate = self
Error:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Destination Controller
var getImage = UIImage()
var name = String()
var gender = String()
var house = String()
var ancestry = String()
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = (charData.image)as! UIImage
nameLabel.text! = name
houseLabel.text! = house
// Do any additional setup after loading the view.
}
Source Controller
var charactersData = [Character]()
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData()
{
DispatchQueue.main.async {
Alamofire.request("http://hp-api.herokuapp.com/api/characters").responseJSON(completionHandler: {
(response) in
switch response.result
{
case.success(let value):
let json = JSON(value)
print(json)
json.array?.forEach({
(character) in
let character = Character(name: character["name"].stringValue, house:character["house"].stringValue,image:character["image"].stringValue, gender: character["gender"].stringValue, ancestry: character["ancestry"].stringValue)
self.charactersData.append(character)
})
self.tableView.reloadData()
case.failure(let error):
print(error.localizedDescription)
}
})
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return charactersData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CharTableViewCell
cell.nameLabel.text = "Name: " + charactersData[indexPath.row].name
cell.houseLabel.text = "House: " + charactersData[indexPath.row].house
if let imageURL = URL(string: self.charactersData[indexPath.row].image) {
DispatchQueue.global().async {
let data = try? Data(contentsOf: imageURL)
if let data = data {
let image = UIImage(data: data)
DispatchQueue.main.async {
cell.charImageView.image = image
}
}
}
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let hpc = storyboard?.instantiateViewController(withIdentifier: "CharDetails") as? CharDetailsViewController
hpc?.getImage = (charactersData[indexPath.row].image) as! UIImage
hpc?.name = charactersData[indexPath.row].name
hpc?.house = charactersData[indexPath.row].house
self.navigationController?.pushViewController(hpc!, animated: true)
}
Im trying to pass an image to another controller but it seems im getting that error, could someone kindly help me. All the other data like name and house is passing properly other than the image. Kindly please let me know where to make changes
This might work:
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = getimage // change this in view did load method
}
You are doing wrong(this is not UIImage, this is URL string so you can use this url string to download the image):
hpc?.getImage = (charactersData[indexPath.row].image) as! UIImage
Please replace UIImage to String because this is not UIImage, This is String URL to download the image
So For this You have to change getImage variable UIImage to String and pass this String to this variable
var getImage = String()
hpc?.getImage = (charactersData[indexPath.row].image) as! String
After that again download this image from URL in another controller but this way is not good so you to follow below way:
Or
You have another option like when you download the image than save it Character Struct and pass it when didselect
Process:
Add a new variable like image in Character Struct/Model
Assign downloaded image when API call in the Struct/Model
And pass this image to another controller when didSelect
I can not display image using firebase in table view cell, I don't know why because my code seems to work, but not there, may anyone help me?
Note: The label Works. I created a custom cell using a cocoa touch class, then I have linked that using the notation to cell as you can see.
import UIKit
import Firebase
class PlacesTableViewController: UIViewController,
UITableViewDataSource, UITableViewDelegate{
let ref = Database.database().reference()
var PlacesRef:DatabaseReference! = nil
var SelectedRef:DatabaseReference! = nil
let storage = Storage.storage()
var postdata:[String] = [String]()
#IBOutlet weak var tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
print("Here Variables")
print("Here translated Names")
PlacesRef = ref.child("Places")
let storageRef = self.storage.reference()
PlacesRef.observe(.value) { (snapshot) in
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
if snapshot.exists() {
for a in ((snapshot.value as AnyObject).allKeys)!{
var now:String = ""
self.postdata.append(a as! String)
DispatchQueue.main.async{
self.tableview.reloadData()
}
}
} else {
print("we don't have that, add it to the DB now")
}
print(self.postdata) //add key to array
}
tableview.delegate = self
tableview.dataSource = self
}
func tableView(_ _tableView: UITableView, numberOfRowsInSection selection: Int) ->Int{
print(postdata)
return postdata.count
}
func tableView( _ tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableview.dequeueReusableCell(withIdentifier: "cell") as! CustomTableViewCell
var image=UIImage()
let StorageRef = storage.reference()
let NationRef = StorageRef.child("Nations/\(postdata[indexPath.row]).jpg")
print("\(postdata[indexPath.row]).jpg")
NationRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print(error)
} else {
// Data for "images/island.jpg" is returned
image = UIImage(data: data!)!
print("image downloaded!")
}
}
cell.DetailLabel.text = postdata[indexPath.row]
cell.DetailImage.image = image
return cell
}
}
Let's see what happens in
func tableView( _ tableview: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableview.dequeueReusableCell(withIdentifier: "cell") as! CustomTableViewCell
var image=UIImage()
let StorageRef = storage.reference()
let NationRef = StorageRef.child("Nations/\(postdata[indexPath.row]).jpg")
// HERE we starting async web request for image data (tag 1)
NationRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print(error)
} else {
// HERE we getting image data from async request and storing it in image var (tag 3)
image = UIImage(data: data!)!
print("image downloaded!")
}
}
cell.DetailLabel.text = postdata[indexPath.row]
// HERE we setting UIImage to cell's imageView (tag 2)
cell.DetailImage.image = image
return cell
}
if printing tags we'll get tag 1, tag 2 and tag 3. It means that firstly you create empty uiimage, then set this image to cell's imageView and at last you change image to image from request (image, not cell's imageView)
I think the answer can be - replace image = UIImage(data: data!)! with cell.DetailImage.image = UIImage(data: data!)
and there are many ways to improve this method
I am currently trying to display firebase objects in my tableview. However, I am only getting empty prototype cells. Thanks if you can take a glance at it!
import UIKit
import Firebase
class UsersTableViewController: UITableViewController {
var user = [User]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getusers() {
let userID = Auth.auth().currentUser?.uid
let rootRef = Database.database().reference()
let query = rootRef.child("users").queryOrdered(byChild: "fullname")
query.observe(.value) { (snapshot) in
for child in snapshot.children.allObjects as! [DataSnapshot] {
if let value = child.value as? NSDictionary {
let userToShow = User()
let fullname = value["fullname"] as? String ?? "Name not found"
let uid = value["uid"] as? String ?? "uid not found"
userToShow.fullname = fullname
userToShow.userID = uid
self.user.append(userToShow)
DispatchQueue.main.async { self.tableView.reloadData() }
}
}
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return user.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath) as! TableViewCell
cell.nameLabel.text = self.user[indexPath.row].fullname
cell.userID = self.user[indexPath.row].userID
cell.userImage.downloadImage(from: self.user[indexPath.row].imagePath!)
return cell
}
}
extension UIImageView {
#objc func downloadImage(from imgURL: String!) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) {
(data, response, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}}
Thanks again for anyone willing to help! I am currently using Swift 4 with Google's Firebase API.
p.s. I know that I have connected delegate and dataSource. I am also sure that I have properly titled my Identifier. Thanks!