Video Plays in several uitableView Cells ios - ios

I have a big issue with my UITableView. im trying to desplay a video when user tap on a perticular cell. but my problem is when i scroll the tableiew, the video is appered in other cells also. how can i prevent this ?
here is my code (Im Using BrihgtCove to show the Video)
class CatagoryOne: UITableViewController,BCOVPlaybackControllerDelegate {
// MARK: - BrightCove Properties
let catalogService = BCOVCatalogService(token:kViewControllerCatalogToken)
var playbackController :BCOVPlaybackController?
var avpvs : AVPlayerViewController?
static var selectedRow : Int?
required init?(coder aDecoder: NSCoder) {
let manager = BCOVPlayerSDKManager.sharedManager();
avpvs = AVPlayerViewController()
playbackController = manager.createPlaybackControllerWithViewStrategy(manager.defaultControlsViewStrategy())
super.init(coder: aDecoder)
playbackController!.analytics.account = kPublistherID
playbackController!.delegate = self
playbackController!.autoAdvance = true
playbackController!.autoPlay = true
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("VideoItemCell", forIndexPath: indexPath) as! NewVideoItemCell
print("indexPath on cellForRowAtIndexPath = " ,indexPath.row)
print("selectedRow on cellForRowAtIndexPath = " ,CellReUseModel.selectedRow)
// Configure the cell...
configureVideoListCell(cell, atRow: indexPath.row)
return cell
}
func configureVideoListCell (cell : NewVideoItemCell,atRow : Int) {
//cell.backgroundColor = Colors.videoListItemColor
cell.videoTitle.textColor = Colors.videoListTextColor
cell.videoTitle.text = videoModel.titleOfVideoList(atRow)
//cell.thumbNail.image = videoModel.thumbnailForVideoItem(atRow)
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! NewVideoItemCell
print("indexpath Row = " ,indexPath.row)
CellReUseModel.selectedRow = indexPath.row
print("Selected Row = " ,CellReUseModel.selectedRow)
//self.tableView.reloadData()
// the Code that plays the video
self.addChildViewController(avpvs!)
avpvs!.view.frame = cell.contentView.bounds
avpvs!.view.autoresizingMask = [.None]
avpvs!.videoGravity = AVLayerVideoGravityResizeAspectFill
cell.contentView.addSubview(self.avpvs!.view)
avpvs!.didMoveToParentViewController(self)
requestContentFromCatalog()
}
}
Please help me with this :(

Related

How to preserve user input in UITableViewCell before dequeue

I'm creating an application in which I need the users to fill out a number of inputs in a UITableViewCell, kinda like a form. When the user taps on the done button, I need to collect those inputs so I can run some calculations and output them on another view controller
Here is the method I used to collect those inputs:
func doneButtonTapped() {
var dict = [String: Any]()
for rows in 0...TableViewCells.getTableViewCell(ceilingType: node.ceilingSelected, moduleType: node.moduleSelected).count {
let ip = IndexPath(row: rows, section: 0)
let cells = tableView.cellForRow(at: ip)
if let numericCell = cells as? NumericInputTableViewCell {
if let text = numericCell.userInputTextField.text {
dict[numericCell.numericTitleLabel.text!] = text
}
} else if let booleanCell = cells as? BooleanInputTableViewCell {
let booleanSelection = booleanCell.booleanToggleSwitch.isOn
dict[booleanCell.booleanTitleLabel.text!] = booleanSelection
}
}
let calculator = Calculator(userInputDictionary: dict, ceiling_type: node.ceilingSelected)
}
The problem I'm having is when the cell is out of view, the user's input is cleared from the memory. Here are two screenshots to illustrate my point:
As you can see, when all the cells appears, the done button managed to store all the inputs from the user, evidently from the console print. However, if the cells are out of view, the inputs from area/m2 are set to nil:
The solution that came to mind was I shouldn't use a dequeue-able cell as I do want the cell to be in memory when it is out-of-view, but many of the stackover community strong against this practice. How should I solve this problem? Thanks!
UPDATE
Code for cellForRow(at: IndexPath)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let node = node else {
return UITableViewCell()
}
let cellArray = TableViewCells.getTableViewCell(ceilingType: node.ceilingSelected, moduleType: node.moduleSelected)
switch cellArray[indexPath.row].cellType {
case .numericInput :
let cell = tableView.dequeueReusableCell(withIdentifier: "numericCell", for: indexPath) as! NumericInputTableViewCell
cell.numericTitleLabel.text = cellArray[indexPath.row].title
return cell
case .booleanInput :
let cell = tableView.dequeueReusableCell(withIdentifier: "booleanCell", for: indexPath) as! BooleanInputTableViewCell
cell.booleanTitleLabel.text = cellArray[indexPath.row].title
return cell
}
}
}
My two custom cells
NumericInputTableViewCell
class NumericInputTableViewCell: UITableViewCell {
#IBOutlet weak var numericTitleLabel: UILabel!
#IBOutlet weak var userInputTextField: UITextField!
}
BooleanInputTableViewCell
class BooleanInputTableViewCell: UITableViewCell {
#IBOutlet weak var booleanTitleLabel: UILabel!
#IBOutlet weak var booleanToggleSwitch: UISwitch!
}
Any takers?
I agree with the other contributors. The cells should not be used for data storage. You should consider another approach (like the one HMHero suggests).
But, as your question was also about how to access a UITableViewCell before it is removed, there is a method in UITableViewDelegate that you can use for that:
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// do something with the cell before it gets deallocated
}
This method tells the delegate that the specified cell was removed from the table. So it gives a last chance to do something with that cell before it disappears.
Because of table view reuses its cells, usually, it's not a good idea if your data depends on some components from the table view cell. Rather, it should be the other way around. Your table view data always drive it's table view cell's component even before any user input data is provided in your case.
Initial Data - your should already have somewhere in your code. I created my own from your provided code
let data = CellData()
data.title = "Troffer Light Fittin"
data.value = false
let data2 = CellData()
data2.title = "Length Drop"
data2.value = "0"
cellData.append(data)
cellData.append(data2)
Example
enum CellType {
case numericInput, booleanInput
}
class CellData {
var title: String?
var value: Any?
var cellType: CellType {
if let _ = value as? Bool {
return .booleanInput
} else {
return .numericInput
}
}
}
protocol DataCellDelegate: class {
func didChangeCellData(_ cell: UITableViewCell)
}
class DataTableViewCell: UITableViewCell {
var data: CellData?
weak var delegate: DataCellDelegate?
}
class NumericInputTableViewCell: DataTableViewCell {
let userInputTextField: UITextField = UITextField()
override var data: CellData? {
didSet {
textLabel?.text = data?.title
if let value = data?.value as? String {
userInputTextField.text = value
}
}
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
userInputTextField.addTarget(self, action: #selector(textDidChange(_:)), for: .editingChanged)
contentView.addSubview(userInputTextField)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func textDidChange(_ textField: UITextField) {
//update data and let the delegate know data is updated
data?.value = textField.text
delegate?.didChangeCellData(self)
}
//Disregard this part
override func layoutSubviews() {
super.layoutSubviews()
textLabel?.frame.size.height = bounds.size.height / 2
userInputTextField.frame = CGRect(x: (textLabel?.frame.origin.x ?? 10), y: bounds.size.height / 2, width: bounds.size.width - (textLabel?.frame.origin.x ?? 10), height: bounds.size.height / 2)
}
}
class BooleanInputTableViewCell: DataTableViewCell {
override var data: CellData? {
didSet {
textLabel?.text = data?.title
if let value = data?.value as? Bool {
booleanToggleSwitch.isOn = value
}
}
}
let booleanToggleSwitch = UISwitch(frame: .zero)
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
booleanToggleSwitch.addTarget(self, action: #selector(toggled), for: .valueChanged)
booleanToggleSwitch.isOn = true
accessoryView = booleanToggleSwitch
accessoryType = .none
selectionStyle = .none
}
func toggled() {
//update data and let the delegate know data is updated
data?.value = booleanToggleSwitch.isOn
delegate?.didChangeCellData(self)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
In View Controller, you should update your original data source so when you scroll the table view, the data source privide right infomation.
func didChangeCellData(_ cell: UITableViewCell) {
if let cell = cell as? DataTableViewCell {
for data in cellData {
if let title = data.title, let titlePassed = cell.data?.title, title == titlePassed {
data.value = cell.data?.value
}
}
}
for data in cellData {
print("\(data.title) \(data.value)")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = cellData[indexPath.row]
let cell: DataTableViewCell
if data.cellType == .booleanInput {
cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(BooleanInputTableViewCell.self), for: indexPath) as! BooleanInputTableViewCell
} else {
cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(NumericInputTableViewCell.self), for: indexPath) as! NumericInputTableViewCell
}
cell.data = cellData[indexPath.row]
cell.delegate = self
return cell
}
In short, try to have a single data source for table view and use the delegate to pass the updated data in the cell back to the data source.
Please disregard anything that has to do with layout. I didn't use the storyboard to test your requirements.

Custom Cell TextVIew text not changing

I am creating a simple article application in IOS using Swift. I am having issues updating the text inside of my textview. but I have the textView in a custom TableViewCell class and cannot figure out how to change the text. I have also tried making a setter function. I have no error logs, I am printing the contents of the cell after I create it and after I change the text. When I create it it has place holder text, after i change it it IS changed in the cell in cellforRow, but physically displayed is the text from the xib.
import UIKit
class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextViewDelegate {
//mydata
var articles = ["Article","Article","Article","Article","Article","Article","Article"]
var farmers = ["farmer","farmer","farmer","farmer","farmer","farmer","farmer",]
var products = ["coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee","coffee",]
var article = "I am aware that this question has been asked, but none of the answers have worked for me. I'm trying to implement a comments View controller, similar to what you can see in Instagram, where the size of the tableView cell depends on the size of the comment. So I though I would get the necessary height to display the whole comment in textView without scrolling, adjust the textView, then use it to set the heightForRowAtIndexPath appropriately, before finally reloading the table. However, I can't even get to resize the textView, I have tested a certain number of answers and still the textView won't budge."
//flags
var flag = 0 //0=article, 1 = categories, 2 = productpage
// outlets
#IBOutlet weak var tableView: UITableView!
///Default
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let nib1 = UINib(nibName: "Picture2", bundle: nil)
tableView.registerNib(nib1, forCellReuseIdentifier: "Picture2")
let nib2 = UINib(nibName: "Title", bundle: nil)
tableView.registerNib(nib2, forCellReuseIdentifier: "Title")
let nib3 = UINib(nibName: "Article", bundle: nil)
tableView.registerNib(nib3, forCellReuseIdentifier: "Article")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//TableView
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch flag
{
case 0:
return 3
case 1:
return products.count
case 2:
return farmers.count
default:
return 1
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch flag
{
case 0:
if(indexPath.row == 0)
{
return 216;
}
else if(indexPath.row == 1)
{
return 80;
}
else
{
var hieght = calculateHeightForString(article)
return hieght
}
case 1:
return 44
case 2:
return 216
default:
return 216
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
switch flag
{
case 0:
self.performSegueWithIdentifier("View2", sender: self)
case 1:
self.performSegueWithIdentifier("View2", sender: self)
case 2:
//self.performSegueWithIdentifier("Product", sender: self)
break
default:
return self.performSegueWithIdentifier("View2", sender: self)
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch flag
{
case 0:
if(indexPath.row == 0)
{
let cell = self.tableView.dequeueReusableCellWithIdentifier("Picture2", forIndexPath: indexPath) as! Picture2Cell
let imageName = "Bag.png"
let image = UIImage(named: imageName)
cell.Picture.image = image
return cell
}
else if(indexPath.row == 1)
{
let cell = self.tableView.dequeueReusableCellWithIdentifier("Title", forIndexPath: indexPath) as! TitleCell
cell.title.text = "THIS IS THE TTITLE"
cell.by.text = "Zach Chandler"
cell.country.text = "Camaroon"
return cell
}
else
{
var cell = self.tableView.dequeueReusableCellWithIdentifier("Article", forIndexPath: indexPath) as! ArticleCell
print(cell.textView.text)
println("Changed")
let currentText:NSString = article
cell.textView.text = currentText as String
print(cell.textView.text)
return cell
}
case 2:
let cell = self.tableView.dequeueReusableCellWithIdentifier("MainCell", forIndexPath: indexPath) as! Picture1Cell
cell.title.text = "indexpath.section \(indexPath.section)"
let imageName = "Bag.png"
let image = UIImage(named: imageName)
cell.picture.image = image
cell.subtitle.text = "indexPath.row \(indexPath.row)"
return cell
case 1:
let cell = self.tableView.dequeueReusableCellWithIdentifier("ProductCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = products[indexPath.row]
let imageName = "bag.png"
let image = UIImage(named: imageName)
cell.imageView!.image = image
cell.detailTextLabel?.text = "indexpath.row\(indexPath.row)"
return cell
default:
let cell = self.tableView.dequeueReusableCellWithIdentifier("ProductCell", forIndexPath: indexPath) as!
UITableViewCell
cell.textLabel?.text = "indexpath.row\(indexPath.row)"
return cell
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
switch flag
{
case 0:
return 1
case 1:
return 1
case 2:
return farmers.count
default:
return 1
}
}
//segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
}
//personal functions
func calculateHeightForString(inString:String) -> CGFloat
{
var messageString = inString
var attributes = [UIFont(): UIFont.systemFontOfSize(15.0)]
var attrString:NSAttributedString? = NSAttributedString(string: messageString, attributes: attributes)
var rect:CGRect = attrString!.boundingRectWithSize(CGSizeMake(300.0,CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil )
var requredSize:CGRect = rect
return requredSize.height //to include button's in your tableview
}
article class
import UIKit
class ArticleCell: UITableViewCell, UITextViewDelegate {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
#IBOutlet weak var textView: UITextView!
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func SetText(inString: String)
{
textView.text = inString
}
Try setting the delegate before you change the text, in your cellForRowAtIndexPath method. Should be something like
cell.textView.delegate = self

Swift CollectionView ReloadData Acting Weird

I have a Collection View and a button at the top and that button goes through a list of days. For each day, the collection view should be different and I keep track of changes in a dictionary. However, at each press of the button, I want to reload the data, but it's selecting random cells. When data is reloaded, does it run the cellforitematindexpath over again; if not what exactly does it run?
Here's my CellForItem code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("availability", forIndexPath: indexPath) as! AvailabilityCell
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
cell.timeInterval.text = timeIntervals[indexPath.row]
cell.timePeriod.text = timesForIntervals[indexPath.row]
cell.timeInterval.textColor = DARK_BLUE
cell.timePeriod.textColor = DARK_BLUE
cell.backView.layer.cornerRadius = 10
cell.backView.layer.masksToBounds = true
cell.backView.layer.borderColor = DARK_BLUE.CGColor
cell.backView.layer.borderWidth = 1
cell.selected = false
if (tempList[indexPath.row] == 1) {
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
}
return cell
}
Here's my Cell Did Select/Deselect:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 1
self.availability[self.days[index]] = tempList
}
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = DARK_BLUE
cell.backView.backgroundColor = UIColor.whiteColor()
cell.timePeriod.textColor = DARK_BLUE
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 0
self.availability[self.days[index]] = tempList
}
Here's where data is reloaded:
#IBAction func decreaseDay(sender: AnyObject) {
index--
day.text = days[index]
dispatch_async(dispatch_get_main_queue()) {
self.timeCollection.reloadData()
}
if (index == 0) {
back.enabled = false
}
forward.enabled = true
}
Here's a view of what's happening:
How it starts:
When I reload:
I believe you should change the swift collection view to reload the page on the left hand corner. The data is reloaded to select the most prioritized item in the download list. Hope this helps!

Two UITableView in single UIViewcontroller not working properly

I want to implement following functionality in app show pict
But i have following problem show another pict
my code as follow
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if str == "Loading"{
return 0
}else if tableView == tbl2{
return arrSub.count
}else{
return self.displayData.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:customCellInvitation = self.tableView.dequeueReusableCellWithIdentifier("cell")as! customCellInvitation
if tableView == tbl2{
//Code for the load secind table
cell.lblUserName.text = self.arrSub.objectAtIndex(indexPath.row).valueForKey("username") as?String
cell.btnAdd.setImage(UIImage(named: "yes1.png"), forState:(UIControlState.Normal))
return cell
}else{
//Code for the load first table
cell.lblUserName.text = self.displayData.objectAtIndex(indexPath.row).valueForKey("username") as?String
cell.btnAdd.setImage(UIImage(named: "add.png"), forState:(UIControlState.Normal))
cell.btnAdd.setImage(UIImage(named: "yes1.png"), forState:(UIControlState.Selected))
cell.btnAdd.addTarget(self, action: "addData:", forControlEvents: .TouchUpInside)
cell.btnAdd.tag = indexPath.row
}
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 44
}
//function call when user click Plus button
func addData(sender: UIButton!) {
arrSub .addObject(self.displayData .objectAtIndex(sender.tag))
var button:UIButton = sender.viewWithTag(sender.tag) as! UIButton
button.selected=true
button.userInteractionEnabled = false
NSLog("%#", arrSub)
[tbl2 .reloadData()]
}
I would suggest you to move your tableView Datasource and Delegate to separate classes. This is not a good practise at all. You will certainly mess up with your code.
What you are doing make code complexity, you can add you own custom class for tableView and can maintain it it all delegate datasource methods.Add that tableview in current class and with giving frame to it. By this you can add as many number of tableview to a single class and no need to worry about data handling.
Put a frame to this table view, then you can add two frame to a view controller. So add this frame to your view controller, you should adjust the frame width and hight in order to show two tables.
class ViewController: UIViewController {
lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .None
tableView.frame = CGRectMake(20, (self.view.frame.size.height - 54 * 5) / 2.0, (self.view.frame.size.width - 25 * 5), 54 * 5)
tableView.autoresizingMask = .FlexibleTopMargin | .FlexibleBottomMargin | .FlexibleWidth
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.opaque = false
tableView.backgroundColor = UIColor.clearColor()
tableView.backgroundView = nil
tableView.bounces = false
tableView.showsVerticalScrollIndicator = true
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clearColor()
view.addSubview(tableView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// MARK : TableViewDataSource & Delegate Methods
extension LeftMenuViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 54
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
let titles: [String] = ["Home", "Features", "Pricing", "Help", "About Us", "Contact Us"] // put your titles
let images: [String] = ["IconHome", "IconCalendar", "IconProfile", "IconSettings", "IconEmpty", "IconEmpty"] // add images if you want
cell.backgroundColor = UIColor.clearColor() // optional
cell.textLabel?.font = UIFont(name: "HelveticaNeue", size: 21)
cell.textLabel?.textColor = UIColor.whiteColor()
cell.textLabel?.text = titles[indexPath.row]
cell.selectionStyle = .None
cell.imageView?.image = UIImage(named: images[indexPath.row])
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
switch indexPath.row {
case 0:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("TabBar") as! UIViewController
sideMenuViewController?.contentViewController = viewController
sideMenuViewController?.hideMenuViewController()
break // show table navigation view controller
case 1:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("TabBar") as! UIViewController
sideMenuViewController?.contentViewController = viewController
sideMenuViewController?.hideMenuViewController()
break // show table navigation view controller
default:
break
}
}
}
// MARK: UITextFieldDelegate Methods
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:customCellInvitation = self.tableView.dequeueReusableCellWithIdentifier("cell")as! customCellInvitation
if tableView == tbl2{
cell.lblUserName.text = self.arrSub.objectAtIndex(indexPath.row).valueForKey("username") as?String
if str = "yes"{
cell.btnAdd.setImage(UIImage(named: "yes1.png"), forState:(UIControlState.Normal))
}else{
cell.btnAdd.setImage(UIImage(named: "NO.png"), forState:(UIControlState.Normal))
}
return cell
}else{
cell.lblUserName.text = self.displayData.objectAtIndex(indexPath.row).valueForKey("username") as?String
if str = "yes"{
cell.btnAdd.setImage(UIImage(named: "yes1.png"), forState:(UIControlState.Normal))
}else{
cell.btnAdd.setImage(UIImage(named: "NO.png"), forState:(UIControlState.Normal))
}
}
return cell
}

Checking if UITableViewCell is completely visible in Swift

I am using Parse to store users who have videos and then display their videos in a PFQueryTableViewController (subclasses UITableViewController I believe). I want only the video that is in the TableViewCell which is completely visible to automatically play but I'm having difficulty making the right video play. I looked for solutions but everything was in Objective-C, and my attempts to use the solutions in Swift were unsuccessful. Here is my code:
override func scrollViewDidScroll(scrollView: UIScrollView) {
var cells = self.tableView.visibleCells()
var indexPaths = self.tableView.indexPathsForVisibleRows()!
if (cells.count == 1) {
self.checkVisibilityOfCell(cells[0] as! UsersTableViewCell, forIndexPath: indexPaths[0] as! NSIndexPath)
} else if (cells.count == 2) {
self.checkVisibilityOfCell(cells[1] as! UsersTableViewCell, forIndexPath: indexPaths[1] as! NSIndexPath)
} else if (cells.count > 2) {
for i in 1...(cells.count - 1) {
(cells[i] as! UsersTableViewCell).completelyVisible = true
}
}
}
func checkVisibilityOfCell(cell : UsersTableViewCell, forIndexPath : NSIndexPath){
var cellRect : CGRect = self.tableView.rectForRowAtIndexPath(forIndexPath)
cellRect = self.tableView.superview!.convertRect(cellRect, fromView: self.tableView)
var completelyVisible : Bool = self.tableView.frame.contains(cellRect)
cell.completelyVisible = completelyVisible
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell : UsersTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as? UsersTableViewCell
if(cell == nil) {
cell = UsersTableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: cellIdentifier)
}
if let pfObject = object {
let otherUser = pfObject as! PFUser
cell?.userDisplayed = otherUser
if (cell?.completelyVisible == true) {
// Video playing
println("\(cell?.userDisplayed!.username!) is completely visible")
var video1 = pfObject["video1"] as? PFFile
let video1URL = NSURL(string: (video1?.url)!)
objMoviePlayerController = MPMoviePlayerController(contentURL: video1URL)
objMoviePlayerController.movieSourceType = MPMovieSourceType.Unknown
objMoviePlayerController.view.frame = (cell?.userVideo1.bounds)!
objMoviePlayerController.scalingMode = MPMovieScalingMode.AspectFit
objMoviePlayerController.controlStyle = MPMovieControlStyle.None
objMoviePlayerController.repeatMode = MPMovieRepeatMode.One
objMoviePlayerController.shouldAutoplay = true
cell?.userVideo1.addSubview(objMoviePlayerController.view)
objMoviePlayerController.prepareToPlay()
objMoviePlayerController.play()
} else {
println("\(cell?.userDisplayed!.username!) is not completely visible")
}
}
return cell
}
Since some videos do play, I suspect that one or both of the functions scrollViewDidScroll or checkVisibilityOfCell is incorrect. Any help would be appreciated!

Resources