Why can't I wrap \rowcolor in \only? (Beamer)
The \rowcolor
command uses \noalign
to add some code which should not be aligned like the usual table content. The same macro is used to draw the horizontal table lines. It can only be used between rows, i.e. direct after \\
. The \only
already starts the first cell of the row and therefore \noalign
can't work.
Here three different solutions which are getting more and more generic:
One way to make this work is to place the \rowcolor
code into a custom macro which is empty otherwise. This is OK because TeX expands macros at the begin of cells to look for included \noalign
s.
\documentclass[table]{beamer}
\begin{document}
\begin{frame}{Boo}
\begin{table}
\centering
\small
\def\firstrowcolor{}
\def\secondrowcolor{}
\only<1>{\def\firstrowcolor{\rowcolor{green}}}
\only<2>{\def\secondrowcolor{\rowcolor{green}}}
\begin{tabular}{rcc}
\firstrowcolor Hey & 32.0 & 26.7\\
\secondrowcolor Hey & 28.5 & 24.5\\
\end{tabular}
\caption{My caption}
\end{table}
\end{frame}
\end{document}
An alternative would be to change \rowcolor
to accept the beamer
overlay specifications directly:
\documentclass[table]{beamer}
% Redefine `\rowcolor` to allow a beamer overlay specifier
% New syntax: \rewcolor<overlay>[color model]{color}[left overhang][right overhang]
\makeatletter
% Open `\noalign` and check for overlay specification:
\def\rowcolor{\noalign{\ifnum0=`}\fi\bmr@rowcolor}
\newcommand<>{\bmr@rowcolor}{%
\alt#1%
{\global\let\CT@do@color\CT@@do@color\@ifnextchar[\CT@rowa\CT@rowb}% Rest of original `\rowcolor`
{\ifnum0=`{\fi}\@gooble@rowcolor}% End `\noalign` and gobble all arguments of `\rowcolor`.
}
% Gobble all normal arguments of `\rowcolor`:
\newcommand{\@gooble@rowcolor}[2][]{\@gooble@rowcolor@}
\newcommand{\@gooble@rowcolor@}[1][]{\@gooble@rowcolor@@}
\newcommand{\@gooble@rowcolor@@}[1][]{\ignorespaces}
\makeatother
\begin{document}
\begin{frame}{Test}%
\begin{tabular}{ll}
\rowcolor<1>{green} A & B \\
\rowcolor<2>{green} D & C \\
\end{tabular}
\begin{tabular}{ll}
\rowcolor<1>{green}[0pt][1pt] A & B \\
\rowcolor<2>{green}[0pt][1pt] D & C \\
\end{tabular}
\begin{tabular}{ll}
\rowcolor<1>[named]{green}[0pt][1pt] A & B \\
\rowcolor<2>[named]{green}[0pt][1pt] D & C \\
\end{tabular}
\end{frame}
\end{document}
I finally had the idea to provide some overlay aware macros which take row-specific macros like \hline
or \rowcolor
as arguments. This way you
can have different row colors on different slides. There is \rowonly
, \rowalt
and \rowtemporal
which work like \only
, \alt
and \temporal
. See the examples at the end.
\documentclass[table]{beamer}
\makeatletter
\newcommand{\rowonly}{%
\noalign{\ifnum0=`}\fi
\@rowonly
}
\newcommand<>{\@rowonly}[1]{%
\only#2%
{\ifnum0=`{\fi}#1{\ifnum0=`}\fi}%
\ifnum0=`{\fi}%
\ignorespaces
}
\newcommand{\rowalt}{%
\noalign{\ifnum0=`}\fi
\@rowalt
}
\newcommand<>{\@rowalt}[2]{%
\alt#3%
{\ifnum0=`{\fi}#1{\ifnum0=`}\fi}%
{\ifnum0=`{\fi}#2{\ifnum0=`}\fi}%
\ifnum0=`{\fi}%
\ignorespaces
}
\newcommand{\rowtemporal}{%
\noalign{\ifnum0=`}\fi
\@rowtemporal
}
\newcommand<>{\@rowtemporal}[3]{%
\temporal#4%
{\ifnum0=`{\fi}#1{\ifnum0=`}\fi}%
{\ifnum0=`{\fi}#2{\ifnum0=`}\fi}%
{\ifnum0=`{\fi}#3{\ifnum0=`}\fi}%
\ifnum0=`{\fi}%
\ignorespaces
}
\makeatother
\begin{document}
\begin{frame}<1-3>{Test}%
\begin{tabular}{ll}
\rowcolor{blue} A & B \\
\rowonly<1>{\hline} A & B \\
\rowonly<1>{\rowcolor{yellow}} A & B \\
\rowalt<3>{\rowcolor{green}}{\rowcolor{red}} C & D \\
\rowtemporal<2>{\rowcolor{green}}{\rowcolor{yellow}}{\rowcolor{red}} E & F \\
\end{tabular}
\end{frame}
\end{document}
Martin Scharrer explained the problem very well, but I think there is a better (simpler) solution to work around. Try
\documentclass[table]{beamer}
\begin{document}
\begin{frame}{Boo}
\begin{table}
\centering
\small
\begin{tabular}{rcc}
\rowcolor{green}}Hey & 32.0 & 26.7\only<1>{\\}
\only<2>{\\\rowcolor{green}}Hey & 28.5 & 24.5\\
\end{tabular}
\caption{My caption}
\end{table}
\end{frame}
\end{document}