Edit 5
Following the OP's suggestion an alternative solution is to interrupt the covering and restart it (in contrast to locally uncovering the text). This could be done with the following macro:
\newcommand<>{\myinterruptcover}[1]{%
\expandafter\ifx%
\csname beamer@doafter\the\beamer@coveringdepth\endcsname\relax
#1%
\else
\alt#2{\beamer@endcovered #1\beamer@startcovered}{#1}%
\fi
}
The conditional checks if we currently are in a covered region, i.e. if \beamer@doafter<N>
(see below) is defined.
I still prefer the \myuncover
macro, because it just locally undoes the color change of the covering.
Edit 4
@Henry DeYoung asked for an explanation of how I came up with the macro. I added a rather longish one below.
Edit 3
After some more digging in the beamer sources I came up with the following, which also keeps the structure color (by using local color definitions):
\documentclass{beamer}
\makeatletter
\newcommand{\my@endcovered}{%
% check if \beamer@doafterN is different from \relax
% where N is the current covering level
\expandafter\ifx%
\csname beamer@doafter\the\beamer@coveringdepth\endcsname\relax
\else
% reset the color hook, but only locally
% -- in the 'real' \beamer@doafter the global \xdef is used
% instead of \edef
\edef\beamer@colorhook{%
\csname beamer@oldcolorhook\the\beamer@coveringdepth\endcsname}%
% I think the following is not needed here, though I don't really
% know what effect it has
% \edef\beamer@pgfextension{%
% \csname beamer@oldpgfextension\the\beamer@coveringdepth\endcsname}%
% finally, set colors
\color{.}%
\fi%
}%
\newcommand<>{\myuncover}[1]{\alt#2{{\my@endcovered #1}}{#1}}
\makeatother
\setbeamercovered{again covered={\opaqueness<1->{25}}}
\begin{document}
\begin{frame}{Frame Title}
\begin{itemize}[<+>]
\item \myuncover<.->{Who}'s on {\color{structure} first}
\item \myuncover<.->{What}'s on {\color{structure} second}
\item \myuncover<.->{I don't know}'s on {\color{structure} third}
\end{itemize}
\uncover<+>{-- Abbott and Costello}
\end{frame}
\end{document}
I think that solves all the problems.
Explanation
The beamer command \uncover
(like all commands related to overlay features) is defined in beamerbaseoverlay.sty
as
\newcommand{\uncover}{\alt{\beamer@fakeinvisible}{\beamer@makecovered}}
so that \beamer@makecovered
is triggered when the overlay specification matches. That macro, in turn, is defined at the same place as
\long\def\beamer@makecovered#1{\beamer@startcovered#1\beamer@endcovered}
which is why I first suggested to locally use \beamer@endcovered
to end the covering. However, \beamer@endcovered
has some undesired global effects, so it is necessary to go one level deeper. Looking at the macro definition
\def\beamer@endcovered{%
\beamer@smuggle{%
\csname beamer@doafter\the\beamer@coveringdepth\endcsname%
\global\advance\beamer@coveringdepth by -1\relax%
}%
}%
we see that \beamer@endcovered
basically expands to \beamer@doafter<N>
, where <N>
is the current value of the counter \beamer@coveringdepth
, which keeps track of the covering level. Finally, that counter is decreased by 1. As a comment in the sources says, \beamer@smuggle
is used to "smuggle skips past", and I decided to ignore this one for the moment (if anyone reads this who knows better, please correct me).
Now it is getting a bit more complicated: every \beamer@doafter<N>
has a corresponding \beamer@do
. Both macros are defined by \beamer@actions
\def\beamer@actions#1#2{%
\gdef\beamer@do{#1%
\expandafter\gdef\csname beamer@doafter%
\the\beamer@coveringdepth\endcsname{#2}}}
which is executed in \beamer@startcovered
. As you can see, actually the doafter
macro is defined when the do
macro is expanded. The relevant piece of code from \beamer@starcovered
is in the definition of \opaqueness
:
\def\opaqueness<##1>##2{%
\only<##1>{%
\beamer@actions{%
\expandafter\xdef\csname beamer@oldcolorhook%
\the\beamer@coveringdepth\endcsname{\beamer@colorhook}%
\expandafter\xdef\csname beamer@oldpgfextension%
\the\beamer@coveringdepth\endcsname{\beamer@pgfextension}%
{\globalcolorstrue\colorlet{beamer@freeze\the\beamer@coveringdepth}{bg}}%
\xdef\beamer@colorhook{!##2!beamer@freeze%
\the\beamer@coveringdepth\beamer@colorhook}%
\gdef\beamer@pgfextension{!##2opaque}%
\color{.}%
}%
{%
\xdef\beamer@colorhook{\csname beamer@oldcolorhook%
\the\beamer@coveringdepth\endcsname}%
\xdef\beamer@pgfextension{\csname beamer@oldpgfextension%
\the\beamer@coveringdepth\endcsname}%
\color{.}%
}}}%
Here, the \beamer@actions
is called, if the overlay specification matches. The macros \beamer@do
and \beamer@doafter<N>
are then set to the arguments. Now it is obvious that the \beamer@do
macro is responsible for setting the color of the covered object (which depends on the user settings). The previous color hook is saved to a macro named \beamer@oldcolorhook<N>
, where <N>
again is the covering level. Exactly this color hook is then restored when \beamer@doafter
is expanded:
\xdef\beamer@colorhook{\csname beamer@oldcolorhook%
\the\beamer@coveringdepth\endcsname}%
\xdef\beamer@pgfextension{\csname beamer@oldpgfextension%
\the\beamer@coveringdepth\endcsname}%
\color{.}%
and those are just the lines of code we were after. I simply replaced the global \xdef
by the local \gdef
to limit the scope of the color redefinition.
Finally just one bit is missing: as mentioned above this definition of \beamer@doafter
is only true if the overlay specification (of \only
) in \opaqueness
is matched. If that is not the case, the macro does not do anything and is equal to \relax
. So my macro checks if \beamer@doafter
is equal to \relax
in which case it also does nothing.
Edit 2
Now this should really yield the desired result:
\documentclass{beamer}
\setbeamercovered{again covered={\opaqueness<1->{25}}}
\makeatletter
\newcommand*{\myuncover}[1]{%
#1\only<.->{\makebox[0pt][r]{\beamer@endcovered #1}}%
}
\makeatother
\begin{document}
\begin{frame}{Frame Title}
\begin{itemize}[<+>]
\item \myuncover{Who}'s on first
\item \myuncover{What}'s on second
\item \myuncover{I don't know}'s on third
\end{itemize}
\uncover<+>{-- Abbott and Costello}
\end{frame}
\end{document}
Best Answer
From the beamer manual, section 17.6 (Transparency Effects), use
\setbeamercovered
to set the default cover behavior, and override it for old items with theagain covered
option.