2013-07-03 17 views
4

我有一個包含文本視圖以及圖像瀏覽的單元格的tableview。我的項目目前正在使用AutoLayout。我的目標是讓圖像視圖在點擊時全屏顯示。一種選擇是使用模式視圖控制器,但我希望這種工作有點類似於在Facebook應用程序中的圖像敲擊工作,應用程序集中圖像並淡化背景。iOS自動佈局 - 將位於tableviewcell內部的視圖移動到屏幕中心

由於我使用自動佈局,我不能簡單地設置圖像視圖的框架來填充屏幕。相反,我需要使用自動佈局約束。我的圖像視圖有5個約束條件,約束條件設置單元格底部的距離,左側和右側,以及一個控制圖像高度的距離。最後一個是圖像視圖上方的textview和圖像頂部之間的垂直空間約束。雖然這看起來與高度和底部約束有衝突,但由於某種原因,接口生成器迫使我擁有這個。爲了避免出現問題,我將此約束的優先級設置爲小於1000(因爲tableview單元格的高度已設置,所以所有內容都完全適合),因此圖像不應該與textview重疊。

要將圖像居中,我將左右距離設置爲零,並刪除垂直空間約束。爲了使圖像居中,我將中心y對齊約束替換爲底部空間約束,而不是tableviewcell。我想讓它位於屏幕的中心,而不是單元格。

爲了讓我用這個主窗口:

AppDelegate* myDelegate = (((AppDelegate*) [UIApplication sharedApplication].delegate)); 
//access main window using myDelegate.window 

然後,設置約束:

//currently sets the distance from the bottom of the cell to 14 
//changing it... 
[cellselected removeConstraint:cellselected.imagebottomspace]; 
cellselected.imagebottomspace = [NSLayoutConstraint constraintWithItem:cellselected.viewimage attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:myDelegate.window attribute:NSLayoutAttributeCenterY multiplier:0 constant:0]; 
[cellselected addConstraint:cellselected.imagebottomspace]; 

但是,這是行不通的。圖像視圖寬度和高度的變化適用得很好。然而,當讀取imagebottomspace約束時,我得到一個不可滿足的佈局 - 顯然約束與另一個約束相沖突,該約束將底部和圖像視圖之間的距離設置爲14,這是我剛剛刪除的約束。所以它似乎並沒有實際去除約束。

當我繼續並讓應用程序中斷某個約束時,imageview會移動,但會移動到錯誤的位置。它不是集中在屏幕上。它向上和向下移動屏幕。

顯然我在做什麼是不對的。我究竟做錯了什麼?

+0

imageBottomspace是一個IBOutlet,用於在IB中創建一個約束嗎?另外,您看到了什麼行爲 - 是圖像的底部停留在哪裏? – rdelmar

+0

@rdelmar查看我在上面的代碼中所做的更改。 – benjih555

+0

@rdelmar imageBottomspace確實是一個IBOutlet – benjih555

回答

7

所以我想你想是這樣的:

zooming image view demo

首先,你需要知道,當Xcode中4.6.3的,筆尖編輯器(「接口生成器」)有一個錯誤的設置時在表格視圖單元格中設置約束條件。它應該在子視圖和單元格的內容視圖之間創建約束,但是它會在子視圖和單元格本身之間創建約束。這往往會在運行時搞砸佈局。 (此錯誤在Xcode 5及更高版本中得到修復。)

這樣做的結果是,您應該刪除所有在筆尖中的約束並在代碼中重新創建它們,或者只是刪除筆尖並創建單元的代碼中的整個視圖層次結構。

其次,還有一種更簡單的圖像縮放方法。下面是當選擇的小區的基本步驟:

  1. 轉換所選擇的小區的圖像視圖邊界到一個CGRect頂層視圖的座標系英寸
  2. 創建一個新的圖像視圖只是爲了放大並將其框架設置爲CGRect。將其userInteractionEnabled設置爲YES。將其autoresizingMask設置爲靈活的寬度和高度。添加輕擊手勢識別器。
  3. 將新圖像視圖添加爲頂層視圖的子視圖。
  4. 將單元格的圖像視圖的hidden屬性設置爲YES
  5. 在動畫塊中,將新圖像視圖的框架設置爲頂層視圖的邊界。
  6. 禁用表視圖的panGestureRecognizer

當新的圖像視圖被輕敲,反向的過程:

  1. 轉換所選擇的小區的圖像視圖邊界到一個CGRect頂層視圖的座標系英寸
  2. 在動畫塊中,將縮放圖像視圖的框架設置爲CGRect
  3. 在動畫完成塊:
    1. 刪除從它的父縮放圖像視圖。
    2. 將單元格的圖像視圖的hidden屬性設置爲NO
    3. 啓用表格視圖的panGestureRecognizer

既然你不動的原始圖像視圖,你不必與它的約束一塌糊塗。隱藏的視圖仍然參與佈局。

由於您正在使用代碼創建新圖像視圖,因此默認情況下它的translatesAutoresizingMaskIntoConstraints設置爲YES。這意味着您可以設置其框架。自動佈局會自動將框架變成約束。

你可以在this github repository找到完整的源代碼。

+0

謝謝!這種方法比處理約束要簡單得多,也更加優雅。 – benjih555

0

我剛剛遇到類似的問題。我認爲這些問題的原因是UIScrollView中嵌入的視圖存在於與其外部視圖不同的邊界系統中。這首先是滾動工作的有效方式,可以認爲它只是對其包含的視圖應用可變偏移量。 Autolayout不知道如何在這些不同的座標系之間進行轉換,因此任何橋接的約束都不會按照您期望的方式應用。

從埃裏卡Sadun的優秀圖書iOS的自動佈局揭祕(從部分「約束,層次結構和邊界系統」)報價:

「要知道界限系統你不應該涉及的一個按鈕。一些 視圖,例如,與一個單獨的集合內的文本字段 視圖。如果有某種內容畫面有自己的邊界系統 (如集合視圖,滾動視圖和表視圖),不另一種觀點認爲跳 出的是一個完全不同的界限系統。」

相關問題