2015-08-16 3 views
4

Я пытаюсь понять, почему мой подзаголовок не получает штрихи.UIView subview не получает штрихи

Ниже приведен gif, показывающий поведение, с которым я сталкиваюсь: когда я нажимаю голубую кнопку справа, ничего не происходит (предположение о том, что на левом фоне должно измениться цвет). Когда я нажимаю зеленую кнопку слева, он правильно получает событие касания, срабатывает прилагаемое действие TouchDown и меняется цвет представления.

enter image description here

Это «приложение», очевидно, не является реальным приложением и просто предназначены для иллюстрации поведения Я сталкиваюсь. Действительно, то, что мне нужно, - это научиться реализовывать обычный шаблон «выпадающего меню», который вы видите во многих приложениях; обычно с сопровождающей кнопкой гамбургера.

Во многих из этих приложений, похоже, основное содержимое приложения перемещается в сторону, чтобы открыть меню, «скрываясь» под приложением, так или иначе. Я пытаюсь воспроизвести такое же поведение здесь.

Я вставляю здесь свой код ViewController. Код, который вы видите ниже, - это все, что у меня есть.

import UIKit 

class ViewController: UIViewController { 

    var originalX : CGFloat! 
    var originalY : CGFloat! 

    var containerView = UIView() 

    var button : UIButton! 
    var button2 : UIButton! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     originalX  = self.view.frame.origin.x 
     originalY  = self.view.frame.origin.y 

     button = UIButton(frame: CGRectMake(200, 25, 100, 100)) 
     button.backgroundColor = UIColor.greenColor() 
     button.addTarget(self, action: "foo", forControlEvents: .TouchDown) 

     view.addSubview(button) 

     containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) 
     containerView.userInteractionEnabled = true 
     containerView.backgroundColor = UIColor.magentaColor() 
     containerView.clipsToBounds = false 

     button2 = UIButton(frame: CGRectMake(25, 25, 100, 100)) 
     button2.backgroundColor = UIColor.cyanColor() 
     button2.addTarget(self, action: "bar", forControlEvents: .TouchDown) 

     view.addSubview(containerView) 
     containerView.addSubview(button2) 
    } 

    @IBAction func left() { 
     UIView.animateWithDuration(0.3) { 
      self.view.frame = CGRectMake(self.originalX - 150, self.originalY, self.view.frame.width, self.view.frame.height) 
     } 
    } 

    @IBAction func right() { 
     UIView.animateWithDuration(0.3) { 
      self.view.frame = CGRectMake(self.originalX, self.originalY, self.view.frame.width, self.view.frame.height) 
     } 
    } 

    func foo() { 
     UIView.animateWithDuration(1.0) { 
      self.view.backgroundColor = UIColor.redColor() 
     } 
    } 

    func bar() { 
     UIView.animateWithDuration(1.0) { 
      self.view.backgroundColor = UIColor.blueColor() 
     } 
    } 

} 
+0

У меня нет конкретного ответа для вас, но я бы посмотрел на то, как вы анимируете объекты с помощью «рамки», это вероятно, лучше анимировать либо ограничения, либо преобразование. Анимация фрейма может делать сумасшедшие вещи, и нетрудно просто оживить преобразование. – Loxx

ответ

10

containerView является подтаблица из view, но containerView «ы происхождение справа от правого края его родительского вида (view), из-за линии:

containerView.frame = CGRectMake(self.view.frame.width, originalY, 150, self.view.frame.height) 

Любая часть подвид, который за пределами своих границ superview не будут получать события касания. События касания будут передаваться только и распознаваться частями поднабора, которые являются в пределах границ своего супервизора. Вот почему ваша голубая кнопка не загорается при нажатии.

Одним из способов решения это вместо того, чтобы манипулировать каркас view «с, использовать вторичную подвид (назовем его overlayView) для наложения и покрывают containerView, и манипулировать его рамку. Убедитесь, что, по крайней мере, некоторые части обоих представлений находятся в пределах основного вида, чтобы они могли получать события касания.

+0

Спасибо за сообщение @gschandler - ваш ответ мне не совсем понятен. Не могли бы вы отредактировать для ясности? – bitops

+0

Думаю, я понимаю, что вы имеете в виду о overlayView - есть ли у вас фрагмент кода, который вы могли бы поделиться? Мне трудно представить себе на данный момент. – bitops

+0

Также, если это помогает другим - эта ссылка была передана мне по соответствующему вопросу: https://developer.apple.com/library/ios/qa/qa2013/qa1812.html – bitops

0

Необходимо, чтобы основные view были достаточно большими, чтобы принимать события. Используйте self.view.frame.width + 150 в качестве третьего аргумента CGRectMake в left().

Однако это странное и хрупкое решение для всех, что вы пытаетесь сделать. Вы не должны перемещать рамку основного вида. Это должно оставаться покрывающим весь UIWindow, ничего более, не меньше. Вы хотите только оживить subviews и подумать, действительно ли вы используете PageViewController idiom, идиому CollectionView, идиому UIScrollView или идиому SpriteKit. И подумайте о том, почему вы хотите переместить центральные кнопки управления и ваш центральный ярлык, создавая необычный «прыгающий» интерфейс.

Одна хрупкость делает раскладку в viewDidLoad(), что слишком рано в жизненном цикле ViewController. См: wrong frame size in viewDidLoad

Правильный путь хорошие немного больше работы: ограничить пользовательскую UIView подкласс, чтобы заполнить свой основной вид, а затем, если вы должны сделать, не Раскадровку в-коды вычисления макета, сделать это в пределах переопределенного layoutSubviews() методы этого пользовательского подкласса - в этот момент правильная геометрия -. (Однако добавление подвидов в пользовательских UIView подкласса в коде должны не быть сделано в layoutSubviews() `, но вместо того, чтобы при строительстве или СИБ-пробуждающейся времени.)

Вещи получить много проще, если ваш основной вид needn» т двигаться. Если вы свободно читаете Objective-C, попробуйте: http://www.teehanlax.com/blog/custom-uiviewcontroller-transitions/

Затем вы получаете реальное разделение проблем, где ваши настройки слайдов действительно автономны. Цитирование:

Вот взаимодействие, которое мы собираемся создать. Ничего особенного - просто вид, появляющийся с правого края экрана. Что особенностью является то, что мы фактически представляем контроллер вида, даже , хотя контроллер представления остается видимым.

+0

Эй, спасибо за ваш ответ. Я согласен, что изменение ширины не является хорошим решением. Может быть, есть другой момент, который мне не хватает. На самом деле, о чем идет речь, это копирование очень распространенного шаблона меню «выталкивания», который вы видите во многих приложениях. Во многих (не всех) этих приложениях основное окно приложения перемещается для отображения боковой панели. Это тот эффект, который я собираюсь здесь. – bitops

+0

«Приложение» выше, очевидно, не для реального приложения, это очень упрощенная версия проблемы, которую я пытаюсь решить. – bitops

+0

Сердце ответа, то, анимирует только рамки subview. Кроме того, вы не должны полагаться на значения 'frame' и' bounds' в 'viewDidLoad()' – BaseZen

0

Для вашего кода, вы должны добавить containerView к self.view, однако это кадр не в self.view.bounds, поэтому containerView не может получить какой-либо контакт, так что вы должны сделать, это

  • просто убедитесь, что self.view достаточно большой, чтобы содержать containerView, по крайней мере, содержит button2

или

  • просто анимируйте рамку containerView, чтобы сделать ее в self.view