Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 滚动时电子收视指南视图如何更新?_Ios_Swift_Epg - Fatal编程技术网

Ios 滚动时电子收视指南视图如何更新?

Ios 滚动时电子收视指南视图如何更新?,ios,swift,epg,Ios,Swift,Epg,我的意思是,最初有虚拟数据,然后加载数据 我正在使用EPG的集合视图。我希望动态加载数据,同时动态设置集合视图单元格宽度 例如,请查看JIOTV应用程序。我正在尝试在我的应用程序中做同样的事情 下面是我的自定义布局代码 import UIKit class CustomCollectionViewLayout: UICollectionViewLayout { var numberOfColumns = 8 var shouldPinFirstColumn = true var should

我的意思是,最初有虚拟数据,然后加载数据

我正在使用EPG的集合视图。我希望动态加载数据,同时动态设置集合视图单元格宽度

例如,请查看JIOTV应用程序。我正在尝试在我的应用程序中做同样的事情

下面是我的自定义布局代码

import UIKit

class CustomCollectionViewLayout: UICollectionViewLayout {

var numberOfColumns = 8
var shouldPinFirstColumn = true
var shouldPinFirstRow = true
var sectionNumber = 0

var itemAttributes = [[UICollectionViewLayoutAttributes]]()
var itemsSize = [CGSize]()
var contentSize: CGSize = .zero
var arr = [String]()
var generalArr = [[String]]()
var durationArr = [String]()

override func prepare() {
    guard let collectionView = collectionView else {
        return
    }
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    numberOfColumns = appDelegate.timeArr.count//appDelegate.eventNameArr.count //appDelegate.multipleColumns
   // print(numberOfColumns)
    if appDelegate.generalArr.count > 0 {
    durationArr = appDelegate.generalArr[0]
    generalArr = appDelegate.generalArr
    if collectionView.numberOfSections == 0 {
        return
    }

    if itemAttributes.count != collectionView.numberOfSections {
        generateItemAttributes(collectionView: collectionView)
        return
    }
    for section in 0..<collectionView.numberOfSections {
        for item in 0..<collectionView.numberOfItems(inSection: section) {
            if section != 0 && item != 0 {
                continue
            }
            let attributes = layoutAttributesForItem(at: IndexPath(item: item, section: section))!
            if section == 0 {
                var frame = attributes.frame
                frame.origin.y = collectionView.contentOffset.y
                attributes.frame = frame
            }
            if item == 0 {
                var frame = attributes.frame
                frame.origin.x = collectionView.contentOffset.x
                attributes.frame = frame
            }
        }
    }
  }
}

override var collectionViewContentSize: CGSize 
{
    return contentSize
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    return itemAttributes[indexPath.section][indexPath.row]
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    var attributes = [UICollectionViewLayoutAttributes]()
    for section in itemAttributes {
        let filteredArray = section.filter { obj -> Bool in
            return rect.intersects(obj.frame)
        }

        attributes.append(contentsOf: filteredArray)
    }

    return attributes
}

override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
    return true
}

func convertHourtoMin(strTime : String) -> Int {

    var components: Array = strTime.components(separatedBy: ":")
    let hours = Int(components[0]) ?? 0
    let minutes = Int(components[1]) ?? 0
    let seconds = Int(components[2]) ?? 0

    return ((hours * 60) + (minutes) + (seconds / 60))
}
}

// MARK: - Helpers
extension CustomCollectionViewLayout {

func generateItemAttributes(collectionView: UICollectionView) {
    if itemsSize.count != numberOfColumns {
             calculateItemSizes()
       }
    var column = 0
    var xOffset: CGFloat = 0
    var yOffset: CGFloat = 0
    var contentWidth: CGFloat = 0

    itemAttributes = []
    for section in 0..<collectionView.numberOfSections {
        var sectionAttributes: [UICollectionViewLayoutAttributes] = []
            arr = generalArr[section]
           // print("General Array : \(arr)")
           // print("General Array count : \(arr.count)")
            numberOfColumns = arr.count
            durationArr = arr
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
        for index in 0..<numberOfColumns {
            var itemSize = itemsSize[index]
            if numberOfColumns == appDelegate.timeArr.count {
                 itemSize = itemsSize[index]
            }
            else {
                calculateItemSizes()
                 itemSize = itemsSize[index]
            }
 let indexPath = IndexPath(item: index, section: section)
 let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
            attributes.frame = CGRect(x: xOffset, y: yOffset, width: itemSize.width, height: itemSize.height).integral

            if section == 0 && index == 0 {
                // First cell should be on top
                attributes.zIndex = 1024
            } else if section == 0 || index == 0 {
                // First row/column should be above other cells
                attributes.zIndex = 1023
            }
            // Below code with section == 0 and index till end
         /*   if section == 0 && 0 < numberOfColumns {
                attributes.frame = CGRect(x: xOffset, y: yOffset, width: 100, height: 54).integral
            }
        */
            if section == 0 {
                var frame = attributes.frame
                frame.origin.y = collectionView.contentOffset.y
                attributes.frame = frame
            }
            if index == 0 {
                var frame = attributes.frame
                frame.origin.x = collectionView.contentOffset.x
                attributes.frame = frame
            }

            sectionAttributes.append(attributes)

            xOffset += itemSize.width
            column += 1

            if column == numberOfColumns {
                if xOffset > contentWidth {
                    contentWidth = xOffset
                }

                column = 0
                xOffset = 0
                yOffset += itemSize.height
            }
        }

        itemAttributes.append(sectionAttributes)
    }

    if let attributes = itemAttributes.last?.last {
        contentSize = CGSize(width: contentWidth, height: attributes.frame.maxY)
    }
}

func calculateItemSizes() {
    itemsSize = []
  let appDelegate = UIApplication.shared.delegate as! AppDelegate
if numberOfColumns == appDelegate.timeArr.count{
    for index  in 0..<numberOfColumns {
        itemsSize.append(sizeForItemWithColumnIndexA(index))
     }
}
else {
    for index  in 0..<numberOfColumns {
        itemsSize.append(sizeForItemWithColumnIndex(index))
    }
}
 }

    func sizeForItemWithColumnIndex(_ columnIndex: Int) -> CGSize {
    var text: NSString

    switch columnIndex {

    case 0: return CGSize(width: 80, height: 40) //54
        // case 0: return CGSize(width: 106, height: 54)

        //  case 1:
    //     text = "MMM-99"
    default:
        text = "Content"
        //return CGSize(width: 100, height: 54)
        // for Stringresult in durationArr[columnIndex]
        // Below is code to make the cell dynamic
        var width:Float = Float(convertHourtoMin(strTime: durationArr[columnIndex]))
        var actualWidth:Float = Float((width / 60) * 200) // * 100
        actualWidth = actualWidth + actualWidth
       // print("Actual Width : \(actualWidth)")
        return CGSize(width: Int(actualWidth), height: 40) // 54

        //}
    }

    // let size: CGSize = text.size(withAttributes: [kCTFontAttributeName as NSAttributedStringKey: UIFont.systemFont(ofSize: 14.0)])
    // let width: CGFloat = size.width + 16
    return CGSize(width: 100, height: 54)
}
// Below method is for time row in EPG VIEW
func sizeForItemWithColumnIndexA(_ columnIndex: Int) -> CGSize {
    var text: NSString

    switch columnIndex {

    case 0: return CGSize(width: 80, height: 25)
   // case 0: return CGSize(width: 106, height: 54)

  //  case 1:
   //     text = "MMM-99"
    default:
        text = "Content"
        return CGSize(width: 200, height: 25) // originally width : 100
       // for Stringresult in durationArr[columnIndex]
        // Below is code to make the cell dynamic
            var width:Float = Float(convertHourtoMin(strTime: durationArr[columnIndex]))
            var actualWidth:Float = Float((width / 60) * 100)
            actualWidth = actualWidth + actualWidth
           // print("Actual Width : \(actualWidth)")
            return CGSize(width: Int(actualWidth), height: 54)

        //}
    }

   // let size: CGSize = text.size(withAttributes: [kCTFontAttributeName as NSAttributedStringKey: UIFont.systemFont(ofSize: 14.0)])
   // let width: CGFloat = size.width + 16
    return CGSize(width: 100, height: 35)
}
}
导入UIKit
类CustomCollectionViewLayout:UICollectionViewLayout{
var numberOfColumns=8
var shouldInfirstColumn=true
var shouldPinFirstRow=true
var sectionNumber=0
var itemtattributes=[[UICollectionViewLayoutAttribute]]()
var itemsize=[CGSize]()
变量contentSize:CGSize=.0
var arr=[String]()
var generalArr=[[String]]()
var durationArr=[String]()
重写func prepare(){
guard let collectionView=collectionView else{
返回
}
让appDelegate=UIApplication.shared.delegate为!appDelegate
numberOfColumns=appDelegate.timeArr.count//appDelegate.eventNameArr.count//appDelegate.multipleColumns
//打印(数字列)
如果appDelegate.generalArr.count>0{
durationArr=appDelegate.generalArr[0]
generalArr=appDelegate.generalArr
如果collectionView.numberOfSections==0{
返回
}
如果itemAttributes.count!=collectionView.numberOfSections{
GenerateItemAttribute(collectionView:collectionView)
返回
}
对于0..[UICollectionViewLayoutAttribute]中的节{
变量属性=[UICollectionViewLayoutAttribute]()
对于itemAttributes中的节{
让filteredArray=section.filter{obj->Bool进入
返回直线相交(对象帧)
}
attributes.append(contentsOf:filteredArray)
}
返回属性
}
覆盖函数应验证布局(对于边界新边界:CGRect)->Bool{
返回真值
}
func convertHourtoMin(strTime:String)->Int{
var-components:Array=strTime.components(以“:”分隔)
设小时=Int(分量[0])??0
设分钟=Int(分量[1])??0
设秒=Int(分量[2])??0
返回((小时*60)+(分钟)+(秒/60))
}
}
//马克:助手
扩展CustomCollectionViewLayout{
func GenerateItemAttribute(collectionView:UICollectionView){
如果itemsize.count!=numberOfColumns{
calculateItemSizes()
}
变量列=0
变量xOffset:CGFloat=0
变量yOffset:CGFloat=0
var contentWidth:CGFloat=0
itemAttributes=[]
对于0..


对于EPG,您基本上需要计算单元的大小以及每个频道每个程序的位置。

谢谢您的回复。我也在做同样的事情,但加载数据需要更多的时间。我需要一些逻辑来加载数据并在运行时设置单元宽度动态。我还没有找到解决方案。如果有人知道,请告诉我让我知道。我正在集合视图中使用custome layout。是的,加载EPG需要时间,您需要为UI和UX处理这一点。例如,一个改进是使用智能请求生成器+程序帧计算。对用户当时可见的频道请求进行优先级排序-这有助于加载持续时间。另一个改进是我发现的改进是在不滚动的情况下重新加载行(频道的节目)-这有助于动画(看起来更平滑)。谢谢你的回复。我理解,但我不知道如何用代码实现相同的东西。我正在寻找相同的示例代码。我从一开始就试图解决这个问题,但没有成功。你说的EPG是什么意思?我没听说过这样的术语。@nayem EPG是指电子节目指南。这个问题太宽泛了,无法回答在关于SO的帖子中。我建议您看看。@nayem谢谢。我的代码几乎准备好了,只是我需要帮助在EPG视图中动态加载数据。