Digamos que temos um controlador de exibição com uma subvista. a subvisão ocupa o centro da tela com margens de 100 px em todos os lados. Em seguida, adicionamos um monte de pequenas coisas para clicar dentro dessa subview. Estamos apenas usando a subvisão para tirar proveito do novo quadro (x = 0, y = 0 dentro da subvisão é realmente 100.100 na visualização pai).
Então, imagine que temos algo por trás da subvisão, como um menu. Eu quero que o usuário possa selecionar qualquer uma das "pequenas coisas" na subvisão, mas se não houver nada lá, desejo que passem por ela (desde que o fundo esteja claro de qualquer maneira) para os botões atrás dela.
Como posso fazer isso? Parece que o touchesBegan passa, mas os botões não funcionam.
ios
objective-c
iphone
cocoa-touch
ipad
Sean Clark Hess
fonte
fonte
UIButton
que esteja semitransparenteUIView
enquanto a parte não transparenteUIView
ainda responderá a eventos de toque.Respostas:
Crie uma exibição personalizada para seu contêiner e substitua a mensagem pointInside: para retornar false quando o ponto não estiver em uma exibição filho qualificada, como esta:
Rápido:
Objetivo C:
O uso dessa visualização como um contêiner permitirá que qualquer um de seus filhos receba toques, mas a própria visualização será transparente para os eventos.
fonte
Eu também uso
Não há necessidade de subclasse. Funciona bem.
fonte
Da Apple:
Prática recomendada de maçãs :
em vez disso, você pode substituir:
na sua subclasse UIView e retorne NO se desejar que esse toque seja enviado para a cadeia de respostas (ou seja, para visualizações por trás da visualização sem nada).
fonte
NO
;Uma maneira muito mais simples é "Desmarcar" a interação do usuário ativada no construtor de interfaces. "Se você estiver usando um storyboard"
fonte
Com base no que João postou, aqui está um exemplo que permitirá que os eventos de toque passem por todas as subvisões de uma exibição, exceto pelos botões:
fonte
UIView
subclassePassThroughView
que apenas substitui-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { return YES; }
se você deseja encaminhar eventos de toque para as vistas abaixo.Ultimamente, escrevi uma aula que vai me ajudar com isso. Usá-lo como uma classe personalizada para um
UIButton
ouUIView
passará por eventos de toque que foram executados em um pixel transparente.Essa solução é um pouco melhor do que a resposta aceita porque você ainda pode clicar em uma
UIButton
que esteja semitransparenteUIView
enquanto a parte não transparenteUIView
ainda responderá a eventos de toque.Como você pode ver no GIF, o botão Giraffe é um retângulo simples, mas os eventos de toque em áreas transparentes são passados para o amarelo
UIButton
abaixo.Link para a aula
fonte
A solução mais votada não estava funcionando totalmente para mim, acho que era porque eu tinha um TabBarController na hierarquia (como um dos comentários assinala). A capacidade do tableView de interceptar eventos de toque, o que finalmente fez foi substituir o hitTest na exibição que eu quero ignorar os toques e deixar que as subvisões dessa exibição os manipulem
fonte
Swift 3
fonte
De acordo com o 'Guia de programação de aplicativos do iPhone':
http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/EventHandling/EventHandling.html
Atualizado : exemplo removido - reler a pergunta ...
Você tem algum processamento de gesto nas visualizações que podem estar processando os toques antes que o botão atinja? O botão funciona quando você não tem uma visão transparente?
Algum exemplo de código que não funciona?
fonte
Até onde eu sei, você deve conseguir fazer isso substituindo o método hitTest:. Eu tentei, mas não consegui fazê-lo funcionar corretamente.
No final, criei uma série de visualizações transparentes ao redor do objeto tocável, para que não o cobrissem. Um pouco de um truque para o meu problema funcionou bem.
fonte
Tomando dicas das outras respostas e lendo a documentação da Apple, criei esta biblioteca simples para solucionar seu problema:
https://github.com/natrosoft/NATouchThroughView
Torna fácil desenhar visualizações no Interface Builder que devem passar detalhes para uma visão subjacente.
Acho que o método swizzling é um exagero e muito perigoso de fazer no código de produção, porque você está mexendo diretamente com a implementação básica da Apple e fazendo uma alteração em todo o aplicativo que pode causar conseqüências não intencionais.
Existe um projeto de demonstração e espero que o README faça um bom trabalho explicando o que fazer. Para abordar o OP, você alteraria o UIView claro que contém os botões para classificar NATouchThroughView no Interface Builder. Em seguida, encontre a UIView clara que se sobrepõe ao menu que você deseja ativar. Altere esse UIView para a classe NARootTouchThroughView no Interface Builder. Pode até ser a UIView raiz do seu controlador de exibição, se você deseja que esses toques passem para o controlador de exibição subjacente. Confira o projeto de demonstração para ver como ele funciona. É realmente muito simples, seguro e não invasivo
fonte
Eu criei uma categoria para fazer isso.
um pequeno método swizzling e a vista é dourada.
O cabeçalho
O arquivo de implementação
Você precisará adicionar meus Swizz.he Swizz.m
localizado aqui
Depois disso, basta importar o UIView + PassthroughParent.h no seu arquivo {Project} -Prefix.pch e todas as visualizações terão essa capacidade.
toda visualização terá pontos, mas nenhum espaço em branco.
Eu também recomendo usar um fundo claro.
EDITAR
Criei minha própria sacola de propriedade e isso não foi incluído anteriormente.
Arquivo de cabeçalho
Arquivo de Implementação
fonte
pointInside: withEvent:
?Se você não puder usar um UIView de categoria ou subclasse, também poderá avançar o botão para que fique na frente da visualização transparente. Isso nem sempre será possível, dependendo da sua aplicação, mas funcionou para mim. Você sempre pode trazer o botão de volta ou ocultá-lo.
fonte
Tente isto
fonte
Tente definir um
backgroundColor
dos seustransparentView
comoUIColor(white:0.000, alpha:0.020)
. Então você pode obter eventos de toque emtouchesBegan
/touchesMoved
methods. Coloque o código abaixo em algum lugar da sua visualização:fonte
Eu uso isso em vez de substituir o ponto do método (dentro: CGPoint, com: UIEvent)
fonte