2017-01-19 17 views
0

古いコードを再訪するiOSアプリケーションを開発するときにコードの仕組みを学び始めたので、godlike viewControllerをお詫びします。アプリを実行するときの問題は、ユーザーが一度テーブルビューをスクロールし始めると、ラベルが互いの上に重複し始めていることと、ウェブビューがスタッキングしている可能性が高いことです。私はcell.contentview.addsubview()メソッドを使ってセル内のサブビューを追加するコードを変更しようとしましたが、スクロール時にスタックの振る舞いは変わりません。 dequeueReusableCellWithIdentifier()メソッドも使用しています。これは、画面から消えると同時にすべてのセルがクリアされると思っていました。再利用可能なUITableViewCellスクロールのスクロールを複製する

私がまだ学んでいるので、ここの助けがあれば幸いです。前もって感謝します。 cellForRowAtIndexPathで

Sample Screenshot

import UIKit 

class VimeoFeedViewController: UIViewController, NSXMLParserDelegate, UITableViewDataSource, UIWebViewDelegate, UITableViewDelegate 
{ 

    @IBOutlet var tbData: UITableView? 

    var parser = NSXMLParser() 
    var posts = NSMutableArray() 
    var elements = NSMutableDictionary() 
    var element = NSString() 
    var title1 = NSMutableString() 
    var date = NSMutableString() 
    var link = NSMutableString() 
    var webView = UIWebView() 
    var boxView = UIView() 
    var selectedCell = NSIndexPath() 
    var valueToPass:String! 
    var viewToPass: UIView! 
    var customWebView = UIWebView() 
    var url = NSURL() 





    //custom code for webviews to show up 
    var postTitle: String = String() 
    var postLink: String = String() 
    var ename: String = String() 
    //end of custom code for webviews to show up 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.beginParsing() 
     self.tbData?.backgroundColor = UIColor(patternImage: UIImage(named: "home-page-background.png")!) 
     webView.delegate = self 

    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func beginParsing() 
    { 
     posts = [] 
     parser = NSXMLParser(contentsOfURL:(NSURL(string:"https://vimeo.com/channels/1000464/videos/rss"))!)! 
     parser.delegate = self 
     parser.parse() 
     tbData!.reloadData() 

    } 

    //XMLParser Methods 

    func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) 
    { 
     element = elementName 
     if (elementName as NSString).isEqualToString("item") 
     { 
      elements = NSMutableDictionary() 
      elements = [:] 
      title1 = NSMutableString() 
      title1 = "" 
      date = NSMutableString() 
      date = "" 
      link = NSMutableString() 
      link = "" 
      postTitle = String() 
      postLink = String() 

     } 
    } 

    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) 
    { 
     if (elementName as NSString).isEqualToString("item") { 
      if !title1.isEqual(nil) { 
       elements.setObject(title1, forKey: "title") 
      } 
      if !date.isEqual(nil) { 
       elements.setObject(date, forKey: "date") 
      } 
      if !link.isEqual(nil) { 
       elements.setObject(link, forKey: "link") 
      } 

      posts.addObject(elements) 
     } 
    } 

    func parser(parser: NSXMLParser, foundCharacters string: String) 
    { 
     if element.isEqualToString("title") { 
      title1.appendString(string) 
     } 
     if element.isEqualToString("pubDate") { 
      date.appendString(string) 
     } 
     if element.isEqualToString("link") { 
      link.appendString(string) 
     } 
    } 

    //Tableview Methods 
    func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
     return 100.0 
    } 

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let headerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40)) 
     let imageName = "broughtToYouAG.png" 
     let image = UIImage(named: imageName) 
     let imageView = UIImageView(image: image!) 
     imageView.frame = CGRect(x: 0, y: 0, width: 420, height: 91) 
     headerView.addSubview(imageView) 
     headerView.backgroundColor = UIColor(patternImage: UIImage(named: "home-page-background.png")!) 
     return headerView 
    } 


    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 
     return posts.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ 

     var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell")! 
     if(cell.isEqual(NSNull)) { 
      cell = NSBundle.mainBundle().loadNibNamed("Cell", owner: self, options: nil)![0] as! UITableViewCell; 
     } 
     //start of customization 
     let textLabelCustom = UILabel(frame: CGRectMake(20, 0, 200, 91)) 
     let detailTextLabelCustom = UILabel(frame: CGRectMake(20, 0, 200, 20)) 
     let customWebView:UIWebView = UIWebView(frame: CGRectMake(245, 5, 149, 80)) 

     let url: NSURL? = NSURL(string: posts.objectAtIndex(indexPath.row).valueForKey("link") as! NSString as String) 



     let request: NSURLRequest = NSURLRequest(URL: url!) 
     customWebView.loadRequest(request) 
     customWebView.delegate = self 
     customWebView.scalesPageToFit = true 



     cell.contentView.addSubview(customWebView) 
     cell.contentView.addSubview(boxView) 
     //cell.addSubview(customWebView) 
     //cell.addSubview(boxView) 



     textLabelCustom.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String 

     textLabelCustom.numberOfLines = 4 
     detailTextLabelCustom.numberOfLines = 2 
     textLabelCustom.textColor = UIColor.blackColor() 
     detailTextLabelCustom.font = UIFont(name: "AmericanTypewriter", size: 15) 
     textLabelCustom.font = UIFont(name: "HelveticaNeue", size: 18) 
     //cell.addSubview(textLabelCustom) 
     cell.contentView.addSubview(textLabelCustom) 
     //cell.addSubview(detailTextLabelCustom) 
     cell.contentView.addSubview(detailTextLabelCustom) 
     cell.backgroundColor = UIColor(patternImage: UIImage(named: "home-page-background.png")!) 
     let backgroundView = UIView() 
     backgroundView.backgroundColor = UIColor(patternImage: UIImage(named: "tableselectedimage.png")!) 
     cell.selectedBackgroundView = backgroundView 
     return cell as UITableViewCell 
    } 

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     print("You selected cell #\(indexPath.row)!") 
     let indexPath = tbData!.indexPathForSelectedRow; 
     let url: NSURL? = NSURL(string: posts.objectAtIndex(indexPath!.row).valueForKey("link") as! NSString as String) 
     print("Video url selected: \(url)!") 

    } 


    override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) { 
     if (segue.identifier == "vimeoWebSegue") { 
      //get a reference to the destination view controller 
      let destinationVC: playingThatVideoViewController = segue.destinationViewController as! playingThatVideoViewController 

      let indexPath = tbData!.indexPathForSelectedRow; 

      let url: NSURL? = NSURL(string: posts.objectAtIndex(indexPath!.row).valueForKey("link") as! NSString as String) 

      let titlegoing = posts.objectAtIndex(indexPath!.row).valueForKey("title") as! NSString as String 

      //set properties on the destination view controller 
      destinationVC.videoWebView = customWebView 
      destinationVC.urlbrought = url! 
      destinationVC.titlebrought = titlegoing 

     } 
    } 
} 

答えて

3

あなたはcellForRowAtIndexPathでペン先と適切indexPath.rowに配列から値を必要に応じてセットからこのセルをロードし、望ましいビュー(あなたのケースでは2 UILabelsとのUIWebView)とカスタムのUITableViewCellを作成する必要があります。 cellForRowAtIndexPathにビューを作成したり追加したりしないでください。値を設定するだけです。

+0

これはかなり簡単ですね、これを次に試してみましょう。ありがとうございました –

+1

これは、 'cellForRowAtIndexPath'にビューを追加し、それを削除してリサイクル時に再追加するか、すでにそれらを追加したかどうかを知らせるよりも優れた答えです。ストーリーボードにセルプロトタイプを設定し、それに必要な識別子を付けてタグを付け、カスタムビューにUITableViewCellアウトレットのカスタムサブクラスを与えます。次に、セルを正しいタイプにキャストし、セルのアウトレットを参照します。 –

+0

この方法は、セル内に静的なビュー数がある場合にのみ適切です。セル内のビュー数が動的な場合はどうなりますか?その場合、@HandheldArchitectが質問で行ったように、プログラムでビューを追加する必要があります。だから、質問に再び来て、私はセル内のサブビューを複数回描く同じ問題に直面している。この問題の解決方法はありますか –

1

、再利用のための細胞(それゆえメソッド名「reusableCell」)以来、あなたがセルに多くのサブビューを追加する前に、すべてのセルのサブビューを削除する必要があります。私も、私は思っている dequeueReusableCellWithIdentifier()メソッドを使用してい

for subview in cell.contentView.subviews { 
    subview.contentView.removeFromSuperview() 
} 
+0

を書くのか? –

+0

編集を追加しました – TheAmateurProgrammer

+0

誤ったプログラミング実践 'didEndDisplayingCell'メソッドでもセルのサブビューを削除しないでください。代わりに、これは 'didEndDisplayingCell'の' cell.contentView.removeAllSubviews() 'を使用します。 –

1

は、すべて一緒に、それはそれはセルをクリアしない画面

を消灯した後、細胞をクリアします。

画面に表示されているセルを再利用して、画面に表示されているセルを表示します。 ビューを再度追加する前に削除する必要があります。 これを達成する1つの方法は、ビュー(view.tag = 10)のタグを設定することです。セルをデキューするときは、cell.contentView.viewWithTag(10)?.removeFromSuperview()を実行します。

+0

「それらをもう一度追加する前に」と言うとき、私はaddSubviewメソッドを一度呼び出すだけで何を意味するのかよく分かりません各コンテンツについてセルをクリアするにはどうしたらいいですか? tableView.reloadData()??? –

1

他の回答として、ビューを削除して再追加することをお勧めします。 Idはむしろそれらを一度追加し、ビューを再利用することをお勧めします。セルをサブクラス化し、サブビューを一度追加します。次に、prepareForReuseを使用して、label.text = nilというテキストをクリアします。

パフォーマンス上の理由から、アルファ、編集、選択状態など、コンテンツに関連しないセルの属性のみをリセットする必要があります。

+0

ありがとう、私はUITableViewsドキュメントのprepareForReuseメソッドを見ましたが、viewdidloadの内部に入るか、独自の関数として独自に立つ必要があるかどうかは不明ですし、tableViewControllerがメソッドを自動的に呼び出すでしょうか?私が謝罪しなければ、私がちょうど言ったことが意味をなさないことを願っています。 –

+1

@TheAtlantaGoat viewDidLoadメソッドはViewControllerに属します。必要なのは、メソッドが呼び出されるUITableViewCellサブクラスを作成することです。私は素早くコーディングしていませんが、あなたに例を示すことはできませんが、ここでは、あなたがtableviewCellをサブクラス化してtableviewで正しく使用する方法を示す良いチュートリアルです。 https://www.youtube.com/watch?v=adP2dG_C1XU、基本的にはコンセント/プロパティーをONCEで作成し、セルを再利用するときにそのコンテンツ/テキスト/イメージを変更することです。 –

1

このバグには2つの考えられる理由があります。あなたが他のものを重複しているのと同じ位置に2つのラベルを作成している あなたcellForRowAtIndexPath方法で1

理由。

//Here is your code 
//Check the x-axis and y-axis of both textLabelCustom and detailTextLabelCustom are same. 
//It means both label will place on same axis but with different heights. 
let textLabelCustom = UILabel(frame: CGRectMake(20, 0, 200, 91)) 
let detailTextLabelCustom = UILabel(frame: CGRectMake(20, 0, 200, 20)) 
let customWebView:UIWebView = UIWebView(frame: CGRectMake(245, 5, 149, 80)) 

このように変更します。セルサイズも増やしてください。2

let textLabelCustom = UILabel(frame: CGRectMake(20, 0, 200, 90)) 
let detailTextLabelCustom = UILabel(frame: CGRectMake(20, 90, 200, 20)) 
let customWebView:UIWebView = UIWebView(frame: CGRectMake(245, 5, 149, 80)) 

理由は、別のデリゲートメソッドdidEndDisplayingCellを実装し、それらが再利用される前に、どのようにあなたがサブビューを削除するには線の下に

cell.contentView.removeAllSubviews() 
+0

私はどれほどうんざりしていますか、それを指摘してくれてありがとう。これは恥ずかしいので、あなたの専門知識が正しい方向に向かうことに本当に感謝しています。 –

関連する問題