2016-06-15 8 views
1

nビューをテーブルセル内に追加したい(それぞれのビューが行であると言うことができます)。 designerExpertiseListカウントに基づいて、私は各行のビューを作成し、1画像ビューと1ラベルを追加しました。複数のビューを動的にtableViewCellに動的に追加するときのUIViewの重複

しかし、スクロールすると、セルのデータが正しくありません。セルを長押しすると、現在表示されているビューと重なった別のビューが表示されます。 、初めて正しかったデータをhttp://i.stack.imgur.com/AuTG0.png

と私は上にスクロール:http://i.stack.imgur.com/M8itL.png
私はスクロールダウンした後、再びスクロールアップと長押し:添付のスクリーンショット

にビューがロードされている第一の時間を確認してくださいいくつかの細胞、さらにそれが台無しになっている。私はさらに、First Renderでdynamic viewsを一度だけ追加しようとしました。 tableView cellForRowAtIndexPathメソッド内

let rowHeight:CGFloat = 20.0 
let imageWidth:CGFloat = 15.0 
let imageHeight:CGFloat = 15.0 
let labelX:CGFloat = 30.0 
let labelHeight:CGFloat = 20.0 
var firstRender:[Bool] = [Bool]() 


コード:グローバル宣言があります

self.designer = AppController.getElementFromDesignersList(indexPath.section) 

     cell.designerName.text = designer.getFirstName() + " " + designer.getLastName() 
     cell.location.text = designer.getAddress() 

     // Add more ROWS of expertise if exist! Getting only 1st expertise now, if it exists 
     let expertiseList = self.designer.getExpertiseList() 

     if self.firstRender[indexPath.section] { 
      var i:Int = 0 
      for e in expertiseList { 
       let v = UIView(frame: CGRectMake(0, CGFloat(i)*rowHeight, cell.frame.width, rowHeight)) 
       v.backgroundColor = UIColor.yellowColor() 
       let im = UIImageView(frame: CGRectMake(0, CGFloat(i)*imageHeight, imageWidth, imageHeight)) 
       //print("expertise image path: ", e.getImagePath()) 
       im.af_setImageWithURL(
        NSURL(string: e.getImagePath())!, 
        placeholderImage: UIImage(named: "default_galary_demo2")! 
       ) 

       im.translatesAutoresizingMaskIntoConstraints = false 
       v.addSubview(im) 

       // Adding constraints 
       NSLayoutConstraint(item: im, attribute: .CenterY, relatedBy: .Equal, toItem: v, attribute: .CenterY, multiplier: 1, constant: 0).active = true 
       NSLayoutConstraint(item: im, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: v, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 0.0).active = true 
       im.widthAnchor.constraintEqualToAnchor(nil, constant: imageWidth).active = true 
       im.heightAnchor.constraintEqualToAnchor(nil, constant: imageHeight).active = true 

       // cell.frame.width - im.frame.width - 50 
       let label = UILabel(frame: CGRectMake(0, CGFloat(i)*labelHeight, UIScreen.mainScreen().bounds.width - imageWidth, labelHeight)) 
       label.font = UIFont(name: "OpenSans", size: 12) 
       print("expertise dump: ", dump(e.getExpertiseValuesList())) 
       //print("expertise str: ", e.getExpertiseValuesList().map({"\($0.getName())"}).joinWithSeparator(",")) 
       label.text = e.getExpertiseValuesList().map({"\($0.getName())"}).joinWithSeparator(",") 

       //label.translatesAutoresizingMaskIntoConstraints = false 
       v.addSubview(label) 


       NSLayoutConstraint(item: label, attribute: .CenterY, relatedBy: .Equal, toItem: v, attribute: .CenterY, multiplier: 1, constant: 0).active = true 

       NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: im, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 10.0).active = true 

       cell.designerExpertiseView.addSubview(v) 
       i += 1 
      } 
      self.firstRender[indexPath.section] = false 
+0

制約を追加しますか? 'view.addConstraint'はこちらをご覧くださいhttp://stackoverflow.com/questions/31651022/how-to-create-layout-constraints-programmatically – tbilopavlovic

+0

私は使用しています。 active = trueを指定すると、制約が有効になります。個別に制約を追加する必要はありません。少なくともこれは私が読んだものです – kishorer747

答えて

0

が、私は、ユーザーのスクロールテーブルビューので、それが正しい場合にのみ、if self.firstRender[indexPath.section]セルをレンダリングするとは思いません、画面外のセルは他のインデックスパスを示すために再利用されます。 もう1つ、制約を作成しますが、使用しません。

+0

私は動的に追加している要素に対してのみこの条件を追加しました。他のUI要素がレンダリングされます。私は制約を作成し、直接アクティブにすることによって活性化する。アクティブ= true – kishorer747

+0

セルがレンダリングされると仮定します。たとえば、indexPath(0、)のセル、デリゲートメソッド 'cellForRowAtIndexPath'が呼び出され、コードがサブビューを動的に正しく追加します。 'self.firstRender [0]'は真です。次に、ユーザーのスクロール・テーブル・ビューでは、セル(0、0)が不可視になり、セル(0、0)は別のセルで再利用されます。 'self.firstRender [0]'がfalseであるため、cell(0、0)が再び見えるようになると 'cellForRowAtIndexPath'のコードは実行されません。 –

+0

ダイナミックビューを同じセルに複数回追加することができないと思ったので、firstRenderチェックを追加しました。しかし、今私は別のアプローチをとると思います。私は3行を持っています。必要でない場合は、サブビューを削除するだけです。 – kishorer747

0

制約を処理するためにUIStackViewを使用できます。

  1. クラスの定型文の制約コードを大幅に減らすことができます。
  2. サブビューの追加を簡略化します。
  3. アダプティブレイアウトを許可します。

UITableViewCellに垂直UIStackViewForを追加します。さらに複雑なレイアウトの場合は、垂直スタックビューにUIStackViewを埋め込むか、AutoLayoutとUIStackViewsを混在させることができます。

Using a UIStackView

私はすぐにあなたのレイアウトを再作成しようとしたと私はUIStackViewを追加しました。この実装では、固定のコンポーネント(プロファイル画像のようなもの)に対してAutoLayoutを使用し、プログラムで追加されたUILabelsを処理するためのスタックビューを使用します。

こちらがお役に立てば幸いです。

+0

こんにちは、スタックビューはiOS 9+のためだけに使用したくありません。いくつかのユーザーがまだiOS 7とiOS 8にいるインドのユーザーをターゲットにしています。スタックビューは非常に有望なようでしたが、私は上記の理由と同じ理由でそれを使用しないことにしました – kishorer747

0

このように、.addSubView()を使用してセルにプログラムでビューを追加すると、再利用可能なセルではうまくいきません。これは、ビューから外に出るとセルが再利用されるために発生しますが、再び表示されると、サブビューが再び追加されます。

私が使用した解決策は、ストーリーボードから別のプレースホルダビューを追加することでした。そして、必要がない場合は、.removeFromSuperview()を使用してスーパービューからビューを削除しました。

私はこの方法が良くないと知っています 例:10個のビューをセルに入れます(10個は最大のビューが必要です)。だから私は彼らの大部分を見解から取り除くでしょう。

私はまだこの問題のより良い/実際の解決策を探しています。