Checking if UITableViewCell is completely visible in Swift - uitableview

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!

Related

Can not update the value in class

This is my class Designed.
open class SBCity: NSObject {
var CM_CityID:String = ""
var CM_CityName:String = ""
var CM_OrderBy:Int = 0
required public init(CM_CityID:String,CM_CityName:String,CM_OrderBy:Int) {
self.CM_CityID = CM_CityID
self.CM_CityName = CM_CityName
self.CM_OrderBy = CM_OrderBy
}
}
ViewController
In the ViewController I have the tableView contain the following three details in each cell. I just append the value in the class on my UITableView didSelect method.
var source:SBCity?
var destination:SBCity?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if filterdata.count != 0 {
return filterdata.count
} else {
if tableView == FirstTable {
return ArrcityList.count
} else {
return ArrcityList.count
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == FirstTable{
let cell = tableView.dequeueReusableCell(withIdentifier: "RecentCityCell") as! RecentCityCell
cell.cities = ArrcityList[indexPath.row]
return cell
}
//if tableView is not table1 then
if filterdata.count != 0 {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "SourceCityCell")
as! SourceCityCell
cell2.cities = filterdata[indexPath.row]
return cell2
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: "SourceCityCell")
as! SourceCityCell
cell2.cities = ArrcityList[indexPath.row]
return cell2
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if isSelectingSource {
if tableView == FirstTable{
let indexPath = tableView.indexPathForSelectedRow
let crrtCell = tableView.cellForRow(at: indexPath!) as! RecentCityCell
self.source = SBCity(CM_CityID: crrtCell.lblID.text!, CM_CityName: crrtCell.lblCity1.text!, CM_OrderBy: 0)
source = SBCity(CM_CityID: crrtCell.lblID.text!, CM_CityName: crrtCell.lblCity1.text!, CM_OrderBy: 0)
SourceCityName = crrtCell.lblCity1.text!
self.moveOnNextVc()
} else {
let indexPath = tableView.indexPathForSelectedRow
let crrtCell = tableView.cellForRow(at: indexPath!) as! SourceCityCell
self.source = SBCity(CM_CityID: crrtCell.lblID2.text!, CM_CityName: crrtCell.lblCity2.text!, CM_OrderBy: 0)
source = SBCity(CM_CityID: crrtCell.lblID2.text!, CM_CityName: crrtCell.lblCity2.text!, CM_OrderBy: 0)
SourceCityName = crrtCell.lblCity2.text!
self.moveOnNextVc()
}
} else if isSelectingDestination {
if tableView == FirstTable{
let indexPath = tableView.indexPathForSelectedRow
let crrtCell = tableView.cellForRow(at: indexPath!) as! RecentCityCell
self.destination = SBCity(CM_CityID: crrtCell.lblID.text!, CM_CityName: crrtCell.lblCity1.text!, CM_OrderBy: 0)
destination = SBCity(CM_CityID: crrtCell.lblID.text!, CM_CityName: crrtCell.lblCity1.text!, CM_OrderBy: 0)
DestinationCityName = crrtCell.lblCity1.text!
self.moveOnNextVc()
} else {
let indexPath = tableView.indexPathForSelectedRow
let crrtCell = tableView.cellForRow(at: indexPath!) as! SourceCityCell
self.destination = SBCity(CM_CityID: crrtCell.lblID2.text!, CM_CityName: crrtCell.lblCity2.text!, CM_OrderBy: 0)
destination = SBCity(CM_CityID: crrtCell.lblID2.text!, CM_CityName: crrtCell.lblCity2.text!, CM_OrderBy: 0)
DestinationCityName = crrtCell.lblCity2.text!
self.moveOnNextVc()
}
}
}
But it does not append the value in the class. it's showing nil every time. What's the wrong with the code?

UITableViewCell with two custom cells - Images keep changing

I am new to iOS programming. So sorry in advance in case my question sounds very naive. I have two custom cells in a UITableViewCell. One displaying images and labels and other displaying banner. I want to display labels with images in 3 cells and then show a banner and this continues.
Currently, I am able to display it as desired but when I scroll, images and banner change positions in cells.
Following is my code:-
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if VideosTableViewController.flag >= 1 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let remoteImageUrlString = imageCollection[indexPath.row]
let imageUrl = NSURL(string:remoteImageUrlString)
let myBlock: SDWebImageCompletionBlock! = {(image:UIImage!, error: NSError!, cachetype:SDImageCacheType!, imageURL: NSURL!) -> Void in
}
//cell.myImageView?.image = nil
cell.myImageView.sd_setImageWithURL(imageUrl, completed: myBlock)
//set label
cell.myImageLabel.text = labelCollection[indexPath.row]
print(cell.myImageLabel?.text)
VideosTableViewController.flag = VideosTableViewController.flag - 1
return cell
}
else
{
let adCell = tableView.dequeueReusableCellWithIdentifier("adCell", forIndexPath: indexPath) as! VideosBannerAdCustomTableViewCell
VideosTableViewController.flag = VideosTableViewController.flag + 3
VideosTableViewController.flag = 3
adCell.videosBannerView.adUnitID = "banner id"
adCell.videosBannerView.rootViewController = self
let request : DFPRequest = DFPRequest()
//request.testDevices = [kGADSimulatorID]
request.testDevices = ["my test device id"]
adCell.videosBannerView.loadRequest(request)
return adCell
}
}
Try to use indexPath to determine which cell should be used. You are trying to display adCell with a banner in cell 4th, 8th, .... So it is very simple to be done by this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row % 4 != 0 || indexPath.row == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let remoteImageUrlString = imageCollection[indexPath.row]
let imageUrl = NSURL(string:remoteImageUrlString)
let myBlock: SDWebImageCompletionBlock! = {(image:UIImage!, error: NSError!, cachetype:SDImageCacheType!, imageURL: NSURL!) -> Void in
}
//cell.myImageView?.image = nil
cell.myImageView.sd_setImageWithURL(imageUrl, completed: myBlock)
//set label
cell.myImageLabel.text = labelCollection[indexPath.row]
print(cell.myImageLabel?.text)
VideosTableViewController.flag = VideosTableViewController.flag - 1
return cell
}
else
{
let adCell = tableView.dequeueReusableCellWithIdentifier("adCell", forIndexPath: indexPath) as! VideosBannerAdCustomTableViewCell
VideosTableViewController.flag = VideosTableViewController.flag + 3
VideosTableViewController.flag = 3
adCell.videosBannerView.adUnitID = "banner id"
adCell.videosBannerView.rootViewController = self
let request : DFPRequest = DFPRequest()
//request.testDevices = [kGADSimulatorID]
request.testDevices = ["my test device id"]
adCell.videosBannerView.loadRequest(request)
return adCell
}
}

Use of unresolved identifier 'cell'

I am creating multiple UITableViews in one view controller, and i have used the following code to check for which tableView it is. I keep getting the problem "Use of unresolved identifier 'cell' in the very last line. I have tried searching for this, but there are not many which are up to date at Xcode 7. Forgive me for my lack of terminology as well as experience, for i am just starting off. Please feel free to ask me of any questions that you might encounter. Thank you all in advance who took the time to read this!
#IBOutlet var tableView1: UITableView!
#IBOutlet var tableView2: UITableView!
// Mens games Variables
var dates = ["7/23", "7/24","7/25","7/26","7/27","7/28","7/29"]
var times = ["7:30","8:00","8:30","9:00","9:30","10:00","10:30"]
var teamsOne = ["VU Reserves 1","VU Reserves 3","VU Reserves 5","VU Reserves 7","VU Reserves 9","VU Reserves 11","VU Reserves 13"]
var teamsTwo = ["VU Reserves 2","VU Reserves 4","VU Reserves 6","VU Reserves 8","VU Reserves 10","VU Reserves 12","VU Reserves 14"]
var fields = ["Turf","Field 1","Field 2","Field 3","Field 4","Field 5","Field 6"]
// Womens games Variables
var womensDates = ["7/23", "7/24","7/25","7/26","7/27","7/28","7/29"]
var womensTimes = ["7:30","8:00","8:30","9:00","9:30","10:00","10:30"]
var womensTeamsOne = ["VU Girls 1","VU Girls 3","VU Girls 5","VU Girls 7","VU Girls 9","VU Girls 11","VU Girls 13"]
var womensTeamsTwo = ["VU Girls 2","VU Girls 4","VU Girls 6","VU Girls 8","VU Girls 10","VU Girls 12","VU Girls 14"]
var womensFields = ["Turf","Field 1","Field 2","Field 3","Field 4","Field 5","Field 6"]
override func viewDidLoad() {
super.viewDidLoad()
tableView1.dataSource = self
tableView1.delegate = self
tableView1.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell1")
tableView2.dataSource = self
tableView2.delegate = self
tableView2.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell2")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (tableView == tableView1) {
return teamsOne.count
}
else if (tableView == tableView2) {
return womensTeamsOne.count
} else{
return 0 }
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (tableView == tableView1) {
let cell = self.tableView1.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! gamesCustomCell
cell.date.text = dates[indexPath.row]
cell.time.text = times[indexPath.row]
cell.teamOne.text = teamsOne[indexPath.row]
cell.teamTwo.text = teamsTwo[indexPath.row]
cell.field.text = fields[indexPath.row]
return cell
} else if (tableView == tableView2) {
let cell = self.tableView2.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as! womensGamesCustomCell
cell.womensDate.text = womensDates[indexPath.row]
cell.womensTime.text = womensTimes[indexPath.row]
cell.womensTeamOne.text = womensTeamsOne[indexPath.row]
cell.womensTeamTwo.text = womensTeamsTwo[indexPath.row]
return cell
}
return cell
}
}
Just replace cellForRowAtIndexPath with below code
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell?
if (tableView == tableView1) {
cell = self.tableView1.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! gamesCustomCell
cell.date.text = dates[indexPath.row]
cell.time.text = times[indexPath.row]
cell.teamOne.text = teamsOne[indexPath.row]
cell.teamTwo.text = teamsTwo[indexPath.row]
cell.field.text = fields[indexPath.row]
}
if (tableView == tableView2) {
cell = self.tableView2.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as! womensGamesCustomCell
cell.womensDate.text = womensDates[indexPath.row]
cell.womensTime.text = womensTimes[indexPath.row]
cell.womensTeamOne.text = womensTeamsOne[indexPath.row]
cell.womensTeamTwo.text = womensTeamsTwo[indexPath.row]
}
return cell!
}
Try this, it worked for me
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (tableView == tableView1) {
let cell = self.tableView1.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! gamesCustomCell
cell.date.text = dates[indexPath.row]
cell.time.text = times[indexPath.row]
cell.teamOne.text = teamsOne[indexPath.row]
cell.teamTwo.text = teamsTwo[indexPath.row]
cell.field.text = fields[indexPath.row]
return cell
} else if (tableView == tableView2) {
let cell = self.tableView2.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as! womensGamesCustomCell
cell.womensDate.text = womensDates[indexPath.row]
cell.womensTime.text = womensTimes[indexPath.row]
cell.womensTeamOne.text = womensTeamsOne[indexPath.row]
cell.womensTeamTwo.text = womensTeamsTwo[indexPath.row]
return cell
}
return UITableViewCell()
}

Video Plays in several uitableView Cells 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 :(

swift update cell accessory type

I am trying to update my table cell accessory type when I tap a cell.
here is the code:
var selectedCellArray :[FriendTableViewCell] = []
var friends: [PFUser] = []
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell = self.tableView(tableView, cellForRowAtIndexPath: indexPath) as FriendTableViewCell
if (selectedCell.accessoryType == UITableViewCellAccessoryType.None){
selectedCell.accessoryType = .Checkmark
selectedCellArray.append(selectedCell)
}else if (selectedCell.accessoryType == UITableViewCellAccessoryType.Checkmark){
selectedCell.accessoryType = .None
var index = 0
for cell in selectedCellArray{
if (cell != selectedCell){
index++
}else{
break
}
}
selectedCellArray.removeAtIndex(index)
}
self.tableView(tableView, cellForRowAtIndexPath: indexPath)
}
and
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("friend") as? FriendTableViewCell ?? FriendTableViewCell()
var round = 0
var friend: AnyObject = self.friends[indexPath.row]
cell.firstNameLabel.text = friend["firstName"] as? String
cell.lastNameLabel.text = friend["lastName"] as? String
println(selectedCellArray)
round++
var hasFound = false
if (self.checkSelectedArray(selectedCellArray, target: cell)){
cell.accessoryType = .Checkmark
}else{
cell.accessoryType = .None
}
cell.firstNameLabel.sizeToFit()
cell.lastNameLabel.sizeToFit()
return cell
}
func checkSelectedArray(selectedArray:[FriendTableViewCell], target:FriendTableViewCell) -> Bool{
for cell in selectedCellArray{
if cell.isEqual(target){
return true
}
}
return false
}
Also, is there a built-in method like array.contain? Currently, I wrote a function by myself to check if an array has certain element......
Please help me out... I am stuck for this problem for about 8 hours
Storing the reference to the cell isn't a valid strategy as cells can be re-used when the table scrolls. You can't use the current cell accessory to indicate selection state for the same reason.
You can use an NSIndexSet or a Swift dictionary. Here is an implementation using a dictionary -
var selectedCells :Dictionary<String,PFUser>()
var friends: [PFUser] = []
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell = tableView.cellForRowAtIndexPath(indexPath) as FriendTableViewCell
let objectId=friends[indexPath.row].objectId
if (selectedCells[objectId] != nil){
selectedCell.accessoryType = .None
selectedCells.removeValueForKey(objectId)
} else
selectedCell.accessoryType = .Checkmark
selectedCells[objectId]=friends[indexPath.row]
}
tableView.deselectRowAtIndexPath(indexPath, animated:false)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("friend") as? FriendTableViewCell ?? FriendTableViewCell()
var round = 0
var friend: AnyObject = self.friends[indexPath.row]
cell.firstNameLabel.text = friend["firstName"] as? String
cell.lastNameLabel.text = friend["lastName"] as? String
if (selectedCells[friend.objectId] != nil){
selectedCell.accessoryType = .Checkmark
} else
selectedCell.accessoryType = .None
}
cell.firstNameLabel.sizeToFit()
cell.lastNameLabel.sizeToFit()
return cell
}

Resources